diff --git a/dp/inc/cdp_txrx_cmn_struct.h b/dp/inc/cdp_txrx_cmn_struct.h index 4dcfd5165022..785b2379b288 100644 --- a/dp/inc/cdp_txrx_cmn_struct.h +++ b/dp/inc/cdp_txrx_cmn_struct.h @@ -73,6 +73,21 @@ enum htt_cmn_dbg_stats_type { HTT_DBG_CMN_NUM_STATS }; +/* + * cdp_host_txrx_stats: Different types of host stats + * @TXRX_RX_RATE_STATS: Rx rate info + * @TXRX_TX_RATE_STATS: Tx rate info + * @TXRX_TX_HOST_STATS: Print Tx stats + * @TXRX_RX_HOST_STATS: Print host Rx stats + * @TXRX_CLEAR_STATS: clear all host stats + */ +enum cdp_host_txrx_stats { + TXRX_RX_RATE_STATS = 0, + TXRX_TX_RATE_STATS = 1, + TXRX_TX_HOST_STATS = 2, + TXRX_RX_HOST_STATS = 3, + TXRX_CLEAR_STATS = 4, +}; /** * @brief General specification of the tx frame contents @@ -384,6 +399,7 @@ struct cdp_soc_t { #define TXRX_FW_MAC_PREFETCH_MGR_STATS 23 #define TXRX_FW_STATS_DURATION_INFO 24 #define TXRX_FW_STATS_DURATION_INFO_RESET 25 +#define TXRX_FW_STATS_HOST_RX_STATS 27 #define PER_RADIO_FW_STATS_REQUEST 0 #define PER_VDEV_FW_STATS_REQUEST 1 diff --git a/dp/inc/cdp_txrx_host_stats.h b/dp/inc/cdp_txrx_host_stats.h index 1eaf1fc10d09..cccc9debea59 100644 --- a/dp/inc/cdp_txrx_host_stats.h +++ b/dp/inc/cdp_txrx_host_stats.h @@ -37,24 +37,24 @@ /* Need to rename the function to reflect the functionality "show" / "display" * WIN -- to figure out whether to change OSIF to converge (not an immediate AI) * */ +/** + * cdp_host_stats_get: cdp call to get host stats + * @soc: SOC handle + * @req: Requirement type + * @type: Host stat type + * + * return: 0 for Success, Failure returns error message + */ static inline int cdp_host_stats_get(ol_txrx_soc_handle soc, struct cdp_vdev *vdev, - struct ol_txrx_stats_req *req) + struct ol_txrx_stats_req *req, enum cdp_host_txrx_stats type) { if (soc->ops->host_stats_ops->txrx_host_stats_get) - return soc->ops->host_stats_ops->txrx_host_stats_get(vdev, req); + return soc->ops->host_stats_ops->txrx_host_stats_get(vdev, req, + type); return 0; } - -static inline void -cdp_host_stats_clr(ol_txrx_soc_handle soc, struct cdp_vdev *vdev) -{ - if (soc->ops->host_stats_ops->txrx_host_stats_clr) - return soc->ops->host_stats_ops->txrx_host_stats_clr(vdev); - return; -} - static inline void cdp_host_ce_stats(ol_txrx_soc_handle soc, struct cdp_vdev *vdev) { @@ -213,7 +213,6 @@ cdp_reset_lro_stats(ol_txrx_soc_handle soc, struct cdp_vdev *vdev) 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 432ce043e1ff..cc17014df8e3 100644 --- a/dp/inc/cdp_txrx_ops.h +++ b/dp/inc/cdp_txrx_ops.h @@ -404,9 +404,8 @@ struct cdp_mon_ops { struct cdp_host_stats_ops { int (*txrx_host_stats_get)(struct cdp_vdev *vdev, - struct ol_txrx_stats_req *req); - - void (*txrx_host_stats_clr)(struct cdp_vdev *vdev); + struct ol_txrx_stats_req *req, + enum cdp_host_txrx_stats type); void (*txrx_host_ce_stats)(struct cdp_vdev *vdev); diff --git a/dp/wifi3.0/dp_internal.h b/dp/wifi3.0/dp_internal.h index dd706e40e707..cf098a29d563 100644 --- a/dp/wifi3.0/dp_internal.h +++ b/dp/wifi3.0/dp_internal.h @@ -53,6 +53,52 @@ while (0) #define DP_PRINT(level, fmt, ...) #endif /* DP_PRINT_ENABLE */ +#define DP_TRACE(LVL, fmt, args ...) \ + QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_##LVL, \ + "%s:%d: "fmt, __func__, __LINE__, ## args) + +#define DP_STATS_INIT(_handle) \ + qdf_mem_set(&((_handle)->stats), sizeof((_handle)->stats), 0x0) + +#define DP_STATS_CLR(_handle) \ + qdf_mem_set(&((_handle)->stats), sizeof((_handle)->stats), 0x0) + +#ifndef DISABLE_DP_STATS +#define DP_STATS_INC(_handle, _field, _delta) \ +{ \ + _handle->stats._field += _delta; \ +} + +#define DP_STATS_INCC(_handle, _field, _delta, _cond) \ +{ \ + if (_cond) { \ + _handle->stats._field += _delta; \ + } \ +} + +#define DP_STATS_DEC(_handle, _field, _delta) \ +{ \ + _handle->stats._field -= _delta; \ +} + +#define DP_STATS_UPD(_handle, _field, _delta) \ +{ \ + _handle->stats._field = _delta \ +} + +#define DP_STATS_INC_PKT(_handle, _field, _count, _bytes) \ +{ \ + DP_STATS_INC(_handle, _field.num, _count); \ + DP_STATS_INC(_handle, _field.bytes, _bytes) \ +} +#else +#define DP_STATS_INC(_handle, _field, _delta) +#define DP_STATS_INCC(_handle, _field, _delta, _cond) +#define DP_STATS_DEC(_handle, _field, _delta) +#define DP_STATS_UPD(_handle, _field, _delta) +#define DP_STATS_INC_PKT(_handle, _field, _count, _bytes) +#endif + extern int dp_peer_find_attach(struct dp_soc *soc); extern void dp_peer_find_detach(struct dp_soc *soc); extern void dp_peer_find_hash_add(struct dp_soc *soc, struct dp_peer *peer); @@ -105,4 +151,13 @@ extern QDF_STATUS dp_reo_send_cmd(struct dp_soc *soc, void (*callback_fn), void *data); extern void dp_reo_status_ring_handler(struct dp_soc *soc); +int dp_print_host_stats(struct cdp_vdev *vdev_handle, + struct ol_txrx_stats_req *req, enum cdp_host_txrx_stats type); +void dp_print_pdev_tx_stats(struct dp_pdev *pdev); +void dp_print_pdev_rx_stats(struct dp_pdev *pdev); +void dp_print_soc_tx_stats(struct dp_soc *soc); +void dp_print_soc_rx_stats(struct dp_soc *soc); +void dp_txrx_host_stats_clr(struct dp_vdev *vdev); +void dp_print_rx_rates(struct dp_vdev *vdev); +void dp_print_tx_rates(struct dp_vdev *vdev); #endif /* #ifndef _DP_INTERNAL_H_ */ diff --git a/dp/wifi3.0/dp_main.c b/dp/wifi3.0/dp_main.c index 07fd071690c8..c111100e47c8 100644 --- a/dp/wifi3.0/dp_main.c +++ b/dp/wifi3.0/dp_main.c @@ -30,8 +30,13 @@ #include "dp_rx.h" #include #include +#include "cdp_txrx_cmn_struct.h" #define DP_INTR_POLL_TIMER_MS 100 +#define DP_MCS_LENGTH (6*MAX_MCS) +#define DP_NSS_LENGTH (6*SS_COUNT) +#define DP_RXDMA_ERR_LENGTH (6*MAX_RXDMA_ERRORS) +#define DP_REO_ERR_LENGTH (6*HAL_REO_ERR_QUEUE_DESC_BLOCKED_SET) /** * dp_setup_srng - Internal function to setup SRNG rings used by data path */ @@ -1035,6 +1040,7 @@ static struct cdp_pdev *dp_pdev_attach_wifi3(struct cdp_soc_t *txrx_soc, FL("dp_rx_pdev_attach failed ")); goto fail0; } + DP_STATS_INIT(pdev); #ifndef CONFIG_WIN /* MCL */ @@ -1318,6 +1324,7 @@ static int dp_soc_attach_target_wifi3(struct cdp_soc_t *cdp_soc) dp_rxdma_ring_config(soc); + DP_STATS_INIT(soc); return 0; } @@ -1901,6 +1908,7 @@ static struct cdp_mon_ops dp_ops_mon = { }; static struct cdp_host_stats_ops dp_ops_host_stats = { + .txrx_host_stats_get = dp_print_host_stats, /* TODO */ }; @@ -2098,3 +2106,396 @@ fail1: fail0: return NULL; } + +/* + * dp_print_host_stats()- Function to print the stats aggregated at host + * @vdev_handle: DP_VDEV handle + * @req: ol_txrx_stats_req + * @type: host stats type + * + * Available Stat types + * TXRX_RX_RATE_STATS: Print Rx Rate Info + * TXRX_TX_RATE_STATS: Print Tx Rate Info + * TXRX_TX_HOST_STATS: Print Tx Stats + * TXRX_RX_HOST_STATS: Print Rx Stats + * TXRX_CLEAR_STATS: Clear the stats + * + * Return: 0 on success + */ +int +dp_print_host_stats(struct cdp_vdev *vdev_handle, struct ol_txrx_stats_req *req, + enum cdp_host_txrx_stats type) +{ + struct dp_vdev *vdev = (struct dp_vdev *)vdev_handle; + struct dp_pdev *pdev = (struct dp_pdev *)vdev->pdev; + + switch (type) { + case TXRX_RX_RATE_STATS: + dp_print_rx_rates(vdev); + break; + case TXRX_TX_RATE_STATS: + dp_print_tx_rates(vdev); + break; + case TXRX_TX_HOST_STATS: + dp_print_pdev_tx_stats(pdev); + dp_print_soc_tx_stats(pdev->soc); + break; + case TXRX_RX_HOST_STATS: + dp_print_pdev_rx_stats(pdev); + dp_print_soc_rx_stats(pdev->soc); + break; + case TXRX_CLEAR_STATS: + dp_txrx_host_stats_clr(vdev); + break; + default: + QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_NONE, + "Wrong Input For TxRx Host Stats"); + break; + } + return 0; +} + +/* + * dp_print_pdev_tx_stats(): Print Pdev level TX stats + * @pdev: DP_PDEV Handle + * + * Return:void + */ +void +dp_print_pdev_tx_stats(struct dp_pdev *pdev) +{ + QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_NONE, + "\n WLAN Tx Stats\n"); + QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_NONE, + " Received From Stack\n"); + QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_NONE, + " Total Packets Received: %d ", + pdev->stats.tx.rcvd.num); + QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_NONE, + " Bytes Sent: %d ", + pdev->stats.tx.rcvd.bytes); + QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_NONE, + " Processed\n"); + QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_NONE, + " Msdu Processed: %d ", pdev->stats.tx.processed.num); + QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_NONE, + " Bytes Processed: %d ", + pdev->stats.tx.processed.bytes); + QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_NONE, + " Completions\n"); + QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_NONE, + " Msdu Sent: %d ", pdev->stats.tx.comp.comp_pkt.num); + QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_NONE, + " Bytes Sent: %d ", + pdev->stats.tx.comp.comp_pkt.bytes); + QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_NONE, + " Freed\n"); + QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_NONE, + " Msdus Freed: %d ", pdev->stats.tx.freed.num); + QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_NONE, + " Bytes Freed: %d ", pdev->stats.tx.freed.bytes); + QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_NONE, + " Dropped\n"); + QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_NONE, + " Total Packets Dropped: %d ", + pdev->stats.tx.dropped.dropped_pkt.num); + QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_NONE, + " Bytes Dropped: %d ", + pdev->stats.tx.dropped.dropped_pkt.bytes); + QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_NONE, + " Dma_map_error: %d ", + pdev->stats.tx.dropped.dma_map_error); + QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_NONE, + " Ring Full: %d ", pdev->stats.tx.dropped.ring_full); + QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_NONE, + " Fw Discard: %d ", + pdev->stats.tx.dropped.fw_discard); + QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_NONE, + " Fw Discard Retired: %d ", + pdev->stats.tx.dropped.fw_discard_retired); + QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_NONE, + " Firmware Discard Untransmitted: %d ", + pdev->stats.tx.dropped.firmware_discard_untransmitted); + QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_NONE, + " Mpdu Age Out: %d ", + pdev->stats.tx.dropped.mpdu_age_out); + QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_NONE, + " Firmware Discard Reason1: %d ", + pdev->stats.tx.dropped.firmware_discard_reason1); + QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_NONE, + " Firmware Discard Reason2: %d ", + pdev->stats.tx.dropped.firmware_discard_reason2); + QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_NONE, + " Firmware Discard Reason3: %d ", + pdev->stats.tx.dropped.firmware_discard_reason3); + QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_NONE, + " Scatter Gather\n"); + QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_NONE, + " Total Packets: %d ", pdev->stats.tx.sg.sg_pkt.num); + QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_NONE, + " Total Bytes: %d ", pdev->stats.tx.sg.sg_pkt.bytes); + QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_NONE, + " Dropped By Host: %d ", + pdev->stats.tx.sg.dropped_host); + QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_NONE, + " Dropped By Target: %d ", + pdev->stats.tx.sg.dropped_target); + QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_NONE, + " Tso\n"); + QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_NONE, + " Number of Segments: %d ", + pdev->stats.tx.tso.num_seg); + QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_NONE, + " Number Packets: %d ", + pdev->stats.tx.tso.tso_pkt.num); + QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_NONE, + " Total Bytes: %d ", + pdev->stats.tx.tso.tso_pkt.bytes); + QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_NONE, + " Dropped By Host: %d ", + pdev->stats.tx.tso.dropped_host); + QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_NONE, + " Mcast Enhancement\n"); + QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_NONE, + " Dropped: Map Errors: %d ", + pdev->stats.tx.mcast_en.dropped_map_error); + QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_NONE, + " Dropped: Self Mac: %d ", + pdev->stats.tx.mcast_en.dropped_self_mac); + QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_NONE, + " Dropped: Send Fail: %d ", + pdev->stats.tx.mcast_en.dropped_send_fail); + QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_NONE, + " Total Unicast sent: %d ", + pdev->stats.tx.mcast_en.ucast); +} + +/* + * dp_print_pdev_rx_stats(): Print Pdev level RX stats + * @pdev: DP_PDEV Handle + * + * Return: void + */ +void +dp_print_pdev_rx_stats(struct dp_pdev *pdev) +{ + QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_NONE, + "\n WLAN Rx Stats\n"); + QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_NONE, + " Received From HW (Reo Dest Ring)\n"); + QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_NONE, + " Total Packets Received: %d ", + pdev->stats.rx.rcvd_reo.num); + QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_NONE, + " Bytes Sent: %d ", pdev->stats.rx.rcvd_reo.bytes); + QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_NONE, + " Replenished\n"); + QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_NONE, + " Total Packets Replenished: %d ", + pdev->stats.rx.replenished.num); + QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_NONE, + " Bytes Sent: %d ", pdev->stats.rx.replenished.bytes); + QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_NONE, + " Buffers Added To Freelist: %d ", + pdev->stats.rx.buf_freelist); + QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_NONE, + " Dropped\n"); + QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_NONE, + " Total Packets With No Peer: %d ", + pdev->stats.rx.dropped.no_peer.num); + QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_NONE, + " Bytes Sent With No Peer: %d ", + pdev->stats.rx.dropped.no_peer.bytes); + QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_NONE, + " Total Packets With Msdu Not Done: %d ", + pdev->stats.rx.dropped.msdu_not_done.num); + QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_NONE, + " Bytes Sent With Msdu Not Done: %d ", + pdev->stats.rx.dropped.msdu_not_done.bytes); + QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_NONE, + " Sent To Stack\n"); + QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_NONE, + " Packets Sent To Stack: %d ", + pdev->stats.rx.to_stack.num); + QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_NONE, + " Bytes Sent To Stack: %d ", + pdev->stats.rx.to_stack.bytes); + QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_NONE, + " Errors\n"); + QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_NONE, + " Rxdma Ring Unititalized: %d", + pdev->stats.rx.err.rxdma_unitialized); + QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_NONE, + " Desc Alloc Failed: %d", + pdev->stats.rx.err.desc_alloc_fail); +} + +/* + * dp_print_soc_tx_stats(): Print SOC level stats + * @soc DP_SOC Handle + * + * Return: void + */ +void +dp_print_soc_tx_stats(struct dp_soc *soc) +{ + + QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_NONE, + "\n SOC Tx Stats\n"); + QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_NONE, + " Tx Descriptors In Use: %d ", + soc->stats.tx.desc_in_use); +} + + +/* + * dp_print_soc_rx_stats: Print SOC level Rx stats + * @soc: DP_SOC Handle + * + * Return:void + */ +void +dp_print_soc_rx_stats(struct dp_soc *soc) +{ + uint32_t i; + char reo_error[DP_REO_ERR_LENGTH]; + char rxdma_error[DP_RXDMA_ERR_LENGTH]; + uint8_t index = 0; + + QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_NONE, + "\n SOC Rx Stats\n"); + QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_NONE, + " Errors\n"); + QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_NONE, + " Invalid RBM: %d ", soc->stats.rx.err.invalid_rbm); + QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_NONE, + " Invalid Vdev: %d ", soc->stats.rx.err.invalid_vdev); + QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_NONE, + " Invalid Pdev: %d ", soc->stats.rx.err.invalid_pdev); + QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_NONE, + " HAL Ring Access Fail: %d ", + soc->stats.rx.err.hal_ring_access_fail); + for (i = 0; i < MAX_RXDMA_ERRORS; i++) { + index += qdf_snprint(&rxdma_error[index], + DP_RXDMA_ERR_LENGTH - index, + " %d,", soc->stats.rx.err.rxdma_error[i]); + } + QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_NONE, + " RXDMA Error (0-31):%s", rxdma_error); + index = 0; + for (i = 0; i <= HAL_REO_ERR_QUEUE_DESC_BLOCKED_SET; i++) { + index += qdf_snprint(&reo_error[index], + DP_REO_ERR_LENGTH - index, + " %d,", soc->stats.rx.err.reo_error[i]); + } + QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_NONE, + " REO Error(0-14):%s", reo_error); +} + +/* + * dp_txrx_host_stats_clr(): Reinitialize the txrx stats + * @vdev: DP_VDEV handle + * + * Return:void + */ +void +dp_txrx_host_stats_clr(struct dp_vdev *vdev) +{ + DP_STATS_CLR(vdev->pdev); + DP_STATS_CLR(vdev->pdev->soc); +} + +/* + * dp_print_rx_rates(): Print Rx rate stats + * @vdev: DP_VDEV handle + * + * Return:void + */ +void +dp_print_rx_rates(struct dp_vdev *vdev) +{ + struct dp_pdev *pdev = (struct dp_pdev *)vdev->pdev; + uint8_t i; + uint8_t index = 0; + char mcs[DP_MCS_LENGTH]; + char nss[DP_NSS_LENGTH]; + + QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_NONE, + "\n Rx Rate Info\n"); + for (i = 0; i < MAX_MCS; i++) { + index += qdf_snprint(&mcs[index], DP_MCS_LENGTH - index, + " %d,", pdev->stats.rx.mcs_count[i]); + } + QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_NONE, + " MCS(0-11):%s", mcs); + index = 0; + for (i = 0; i < SS_COUNT; i++) { + index += qdf_snprint(&nss[index], DP_NSS_LENGTH - index, + " %d,", pdev->stats.rx.nss[i]); + } + QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_NONE, + " NSS(0-7):%s", nss); + QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_NONE, + "SGI: 0.8us:%d, 0.4us:%d, 1.6us:%d, 3.2us:%d,", + pdev->stats.rx.sgi_count[0], + pdev->stats.rx.sgi_count[1], + pdev->stats.rx.sgi_count[2], + pdev->stats.rx.sgi_count[3]); + QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_NONE, + "BW Counts: 20MHZ %d, 40MHZ %d, 80MHZ %d, 160MHZ %d", + pdev->stats.rx.bw[0], pdev->stats.rx.bw[1], + pdev->stats.rx.bw[2], pdev->stats.rx.bw[3]); + QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_NONE, + "Reception Type:" + " SU:%d," + " MU_MIMO:%d," + " MU_OFDMA:%d," + " MU_OFDMA_MIMO:%d", + pdev->stats.rx.reception_type[0], + pdev->stats.rx.reception_type[1], + pdev->stats.rx.reception_type[2], + pdev->stats.rx.reception_type[3]); + QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_NONE, + " Aggregation\n"); + QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_NONE, + " Number of Msdu's Part of Ampdu: %d ", + pdev->stats.rx.ampdu_cnt); + QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_NONE, + " Number of Msdu's With No Mpdu Level Aggregation : %d", + pdev->stats.rx.non_ampdu_cnt); + QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_NONE, + " Number of Msdu's Part of Amsdu: %d", + pdev->stats.rx.amsdu_cnt); + QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_NONE, + " Number of Msdu's With No Msdu Level Aggregation: %d", + pdev->stats.rx.non_amsdu_cnt); +} + +/* + * dp_print_tx_rates(): Print tx rates + * @vdev: DP_VDEV handle + * + * Return:void + */ +void +dp_print_tx_rates(struct dp_vdev *vdev) +{ + struct dp_pdev *pdev = (struct dp_pdev *)vdev->pdev; + uint8_t i; + char mcs[DP_MCS_LENGTH]; + uint8_t index = 0; + + QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_NONE, + "\n Tx Rate Info\n"); + + for (i = 0; i < MAX_MCS; i++) { + index += qdf_snprint(&mcs[index], DP_MCS_LENGTH - index, + " %d ", pdev->stats.tx.comp.mcs_count[i]); + } + + QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_NONE, + " MCS(0-11):%s", mcs); + QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_NONE, + " MCS Invalid: %d ", + pdev->stats.tx.comp.mcs_count[MAX_MCS]); +} diff --git a/dp/wifi3.0/dp_rx.c b/dp/wifi3.0/dp_rx.c index 9fa0e814ce2c..741502854539 100644 --- a/dp/wifi3.0/dp_rx.c +++ b/dp/wifi3.0/dp_rx.c @@ -26,6 +26,7 @@ #ifdef MESH_MODE_SUPPORT #include "if_meta_hdr.h" #endif +#include "dp_internal.h" /* * dp_rx_buffers_replenish() - replenish rxdma ring with rx nbufs @@ -63,6 +64,7 @@ QDF_STATUS dp_rx_buffers_replenish(struct dp_soc *dp_soc, uint32_t mac_id, if (!rxdma_srng) { QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_ERROR, "rxdma srng not initialized"); + DP_STATS_INC(dp_pdev, rx.err.rxdma_unitialized, 1); return QDF_STATUS_E_FAILURE; } @@ -81,6 +83,8 @@ QDF_STATUS dp_rx_buffers_replenish(struct dp_soc *dp_soc, uint32_t mac_id, if (!num_alloc_desc) { QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_ERROR, "no free rx_descs in freelist"); + DP_STATS_INC(dp_pdev, rx.err.desc_alloc_fail, + num_alloc_desc); return QDF_STATUS_E_NOMEM; } @@ -138,6 +142,8 @@ QDF_STATUS dp_rx_buffers_replenish(struct dp_soc *dp_soc, uint32_t mac_id, next = (*desc_list)->next; (*desc_list)->rx_desc.nbuf = rx_netbuf; + DP_STATS_INC_PKT(dp_pdev, rx.replenished, 1, + qdf_nbuf_len(rx_netbuf)); hal_rxdma_buff_addr_info_set(rxdma_ring_entry, paddr, (*desc_list)->rx_desc.cookie, owner); @@ -151,6 +157,7 @@ QDF_STATUS dp_rx_buffers_replenish(struct dp_soc *dp_soc, uint32_t mac_id, "successfully replenished %d buffers", num_req_buffers); QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_ERROR, "%d rx desc added back to free list", num_desc_to_free); + DP_STATS_INC(dp_pdev, rx.buf_freelist, num_desc_to_free); /* * add any available free desc back to the free list @@ -392,17 +399,18 @@ dp_rx_process(struct dp_soc *soc, void *hal_ring, uint32_t quota) struct dp_peer *peer = NULL; struct dp_vdev *vdev = NULL; struct dp_vdev *vdev_list[WLAN_UMAC_PSOC_MAX_VDEVS] = { NULL }; + uint32_t pkt_len; struct hal_rx_mpdu_desc_info mpdu_desc_info; struct hal_rx_msdu_desc_info msdu_desc_info; enum hal_reo_error_status error; - uint32_t pkt_len; static uint32_t peer_mdata; uint8_t *rx_tlv_hdr; uint32_t rx_bufs_reaped[MAX_PDEV_CNT] = { 0 }; - uint32_t sgi, rate_mcs, tid; + uint32_t sgi, rate_mcs, tid, nss, bw, reception_type; uint64_t vdev_map = 0; uint8_t mac_id; uint16_t i, vdev_cnt = 0; + uint32_t ampdu_flag, amsdu_flag; /* Debug -- Remove later */ qdf_assert(soc && hal_ring); @@ -469,6 +477,7 @@ dp_rx_process(struct dp_soc *soc, void *hal_ring, uint32_t quota) /* Drop & free packet */ qdf_nbuf_free(rx_desc->nbuf); + /* Statistics */ goto fail; } @@ -503,6 +512,25 @@ dp_rx_process(struct dp_soc *soc, void *hal_ring, uint32_t quota) if (msdu_desc_info.msdu_flags & HAL_MSDU_F_LAST_MSDU_IN_MPDU) qdf_nbuf_set_chfrag_end(rx_desc->nbuf, 1); + DP_STATS_INC_PKT(vdev->pdev, rx.rcvd_reo, 1, + qdf_nbuf_len(rx_desc->nbuf)); + + ampdu_flag = (mpdu_desc_info.mpdu_flags & + HAL_MPDU_F_AMPDU_FLAG); + DP_STATS_INCC(vdev->pdev, rx.ampdu_cnt, 1, ampdu_flag); + DP_STATS_INCC(vdev->pdev, rx.non_ampdu_cnt, 1, !(ampdu_flag)); + + hal_rx_msdu_desc_info_get(ring_desc, &msdu_desc_info); + amsdu_flag = ((msdu_desc_info.msdu_flags & + HAL_MSDU_F_FIRST_MSDU_IN_MPDU) && + (msdu_desc_info.msdu_flags & + HAL_MSDU_F_LAST_MSDU_IN_MPDU)); + + DP_STATS_INCC(vdev->pdev, rx.non_amsdu_cnt, 1, + amsdu_flag); + DP_STATS_INCC(vdev->pdev, rx.amsdu_cnt, 1, + !(amsdu_flag)); + qdf_nbuf_queue_add(&vdev->rxq, rx_desc->nbuf); fail: dp_rx_add_to_free_desc_list(&head[rx_desc->pool_id], @@ -591,6 +619,20 @@ done: "%s: %d, SGI: %d, rate_mcs: %d, tid: %d", __func__, __LINE__, sgi, rate_mcs, tid); + bw = hal_rx_msdu_start_bw_get(rx_tlv_hdr); + reception_type = hal_rx_msdu_start_reception_type_get( + rx_tlv_hdr); + nss = hal_rx_msdu_start_nss_get(rx_tlv_hdr); + + DP_STATS_INC(vdev->pdev, rx.bw[bw], 1); + DP_STATS_INC(vdev->pdev, + rx.reception_type[reception_type], 1); + DP_STATS_INCC(vdev->pdev, rx.nss[nss], 1, + ((reception_type == + RECEPTION_TYPE_MU_MIMO) || + (reception_type == + RECEPTION_TYPE_MU_OFDMA_MIMO))); + /* * HW structures call this L3 header padding -- * even though this is actually the offset from @@ -647,6 +689,7 @@ done: DP_RX_LIST_APPEND(deliver_list_head, deliver_list_tail, nbuf); + DP_STATS_INC(vdev->pdev, rx.to_stack.num, 1); } if (qdf_unlikely(vdev->rx_decap_type == htt_pkt_type_raw)) diff --git a/dp/wifi3.0/dp_rx_err.c b/dp/wifi3.0/dp_rx_err.c index 09e6312a752d..55b1b4fb1a69 100644 --- a/dp/wifi3.0/dp_rx_err.c +++ b/dp/wifi3.0/dp_rx_err.c @@ -375,9 +375,11 @@ dp_rx_null_q_desc_handle(struct dp_soc *soc, struct dp_rx_desc *rx_desc, qdf_nbuf_set_next(nbuf, NULL); vdev->osif_rx(vdev->osif_vdev, nbuf); + DP_STATS_INC(vdev->pdev, rx.to_stack.num, 1); } else { QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_ERROR, FL("INVALID vdev %p OR osif_rx"), vdev); + DP_STATS_INC(soc, rx.err.invalid_vdev, 1); } fail: @@ -421,6 +423,7 @@ dp_rx_link_desc_return(struct dp_soc *soc, void *ring_desc) QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_ERROR, FL("HAL RING Access For WBM Release SRNG Failed - %p"), wbm_rel_srng); + DP_STATS_INC(soc, rx.err.hal_ring_access_fail, 1); goto done; } src_srng_desc = hal_srng_src_get_next(hal_soc, wbm_rel_srng); diff --git a/dp/wifi3.0/dp_tx.c b/dp/wifi3.0/dp_tx.c index b2097b292945..94beb92c9f69 100644 --- a/dp/wifi3.0/dp_tx.c +++ b/dp/wifi3.0/dp_tx.c @@ -120,6 +120,8 @@ dp_tx_desc_release(struct dp_tx_desc_s *tx_desc, uint8_t desc_pool_id) qdf_assert(pdev); soc = pdev->soc; + + DP_STATS_INC(pdev, tx.freed.num, 1); if (tx_desc->flags & DP_TX_DESC_FLAG_FRAG) dp_tx_ext_desc_free(soc, tx_desc->msdu_ext_desc, desc_pool_id); @@ -351,6 +353,8 @@ struct dp_tx_desc_s *dp_tx_prepare_desc_single(struct dp_vdev *vdev, return tx_desc; failure: + DP_STATS_INC_PKT(pdev, tx.dropped.dropped_pkt, 1, + qdf_nbuf_len(nbuf)); dp_tx_desc_release(tx_desc, desc_pool_id); return NULL; } @@ -426,6 +430,8 @@ static struct dp_tx_desc_s *dp_tx_prepare_desc(struct dp_vdev *vdev, return tx_desc; failure: + DP_STATS_INC_PKT(pdev, tx.dropped.dropped_pkt, 1, + qdf_nbuf_len(nbuf)); dp_tx_desc_release(tx_desc, desc_pool_id); return NULL; } @@ -502,6 +508,7 @@ static QDF_STATUS dp_tx_hw_enqueue(struct dp_soc *soc, struct dp_vdev *vdev, void *hal_tx_desc, *hal_tx_desc_cached; qdf_dma_addr_t dma_addr; uint8_t cached_desc[HAL_TX_DESC_LEN_BYTES]; + struct dp_pdev *pdev = (struct dp_pdev *)vdev->pdev; /* Return Buffer Manager ID */ uint8_t bm_id = ring_id; @@ -571,7 +578,9 @@ static QDF_STATUS dp_tx_hw_enqueue(struct dp_soc *soc, struct dp_vdev *vdev, if (!hal_tx_desc) { QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_DEBUG, "%s TCL ring full ring_id:%d\n", __func__, ring_id); - DP_STATS_ADD(soc, tx.tcl_ring_full[ring_id], 1); + DP_STATS_INC(soc, tx.tcl_ring_full[ring_id], 1); + DP_STATS_INC_PKT(pdev, tx.dropped.dropped_pkt, 1, + length); hal_srng_access_end(soc->hal_soc, soc->tcl_data_ring[ring_id].hal_srng); return QDF_STATUS_E_RESOURCES; @@ -580,6 +589,7 @@ static QDF_STATUS dp_tx_hw_enqueue(struct dp_soc *soc, struct dp_vdev *vdev, tx_desc->flags |= DP_TX_DESC_FLAG_QUEUED_TX; hal_tx_desc_sync(hal_tx_desc_cached, hal_tx_desc); + DP_STATS_INC_PKT(pdev, tx.processed, 1, length); return QDF_STATUS_SUCCESS; } @@ -656,6 +666,8 @@ static qdf_nbuf_t dp_tx_send_msdu_single(struct dp_vdev *vdev, qdf_nbuf_t nbuf, return NULL; fail_return: + DP_STATS_INC_PKT(pdev, tx.dropped.dropped_pkt, 1, + qdf_nbuf_len(nbuf)); return nbuf; } @@ -727,6 +739,9 @@ qdf_nbuf_t dp_tx_send_msdu_multiple(struct dp_vdev *vdev, qdf_nbuf_t nbuf, "%s Tx_hw_enqueue Fail tx_desc %p queue %d\n", __func__, tx_desc, tx_q->ring_id); + DP_STATS_INC_PKT(pdev, + tx.dropped.dropped_pkt, 1, + qdf_nbuf_len(tx_desc->nbuf)); dp_tx_desc_release(tx_desc, tx_q->desc_pool_id); goto done; } @@ -946,6 +961,7 @@ qdf_nbuf_t dp_tx_send(void *vap_dev, qdf_nbuf_t nbuf) * (TID override disabled) */ msdu_info.tid = HTT_TX_EXT_TID_INVALID; + DP_STATS_INC_PKT(vdev->pdev, tx.rcvd, 1, qdf_nbuf_len(nbuf)); if (qdf_unlikely(vdev->mesh_vdev)) dp_tx_extract_mesh_meta_data(vdev, nbuf, &msdu_info); @@ -991,7 +1007,8 @@ qdf_nbuf_t dp_tx_send(void *vap_dev, qdf_nbuf_t nbuf) /* dp_tx_prepare_tso(vdev, nbuf, &seg_info, &msdu_info); */ QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_DEBUG, "%s TSO frame %p\n", __func__, vdev); - DP_STATS_MSDU_INCR(soc, tx.tso.tso_pkts, nbuf); + DP_STATS_INC_PKT(vdev->pdev, tx.tso.tso_pkt, 1, + qdf_nbuf_len(nbuf)); goto send_multiple; } @@ -1001,9 +1018,10 @@ qdf_nbuf_t dp_tx_send(void *vap_dev, qdf_nbuf_t nbuf) nbuf = dp_tx_prepare_sg(vdev, nbuf, &seg_info, &msdu_info); QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_DEBUG, - "%s non-TSO SG frame %p\n", __func__, vdev); + "%s non-TSO SG frame %p\n", __func__, vdev); - DP_STATS_MSDU_INCR(soc, tx.sg.sg_pkts, nbuf); + DP_STATS_INC_PKT(vdev->pdev, tx.sg.sg_pkt, 1, + qdf_nbuf_len(nbuf)); goto send_multiple; } @@ -1016,7 +1034,9 @@ qdf_nbuf_t dp_tx_send(void *vap_dev, qdf_nbuf_t nbuf) QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_DEBUG, "%s Mcast frm for ME %p\n", __func__, vdev); - DP_STATS_MSDU_INCR(soc, tx.mcast.pkts, nbuf); + DP_STATS_INC_PKT(vdev->pdev, + tx.mcast_en.mcast_pkt, 1, + qdf_nbuf_len(nbuf)); goto send_multiple; } @@ -1031,7 +1051,9 @@ qdf_nbuf_t dp_tx_send(void *vap_dev, qdf_nbuf_t nbuf) QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_DEBUG, "%s Raw frame %p\n", __func__, vdev); - DP_STATS_MSDU_INCR(soc, tx.raw.pkts, nbuf); + DP_STATS_INC_PKT(vdev->pdev, + tx.raw_pkt, 1, + qdf_nbuf_len(nbuf)); goto send_multiple; @@ -1076,7 +1098,8 @@ void dp_tx_reinject_handler(struct dp_tx_desc_s *tx_desc, uint8_t *status) QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_INFO, "%s Tx reinject path\n", __func__); - DP_STATS_MSDU_INCR(soc, tx.reinject.pkts, tx_desc->nbuf); + DP_STATS_INC_PKT(vdev->pdev, tx.reinject_pkts, 1, + qdf_nbuf_len(tx_desc->nbuf)); if (qdf_unlikely(vdev->mesh_vdev)) { DP_TX_FREE_SINGLE_BUF(vdev->pdev->soc, tx_desc->nbuf); @@ -1110,7 +1133,8 @@ static void dp_tx_inspect_handler(struct dp_tx_desc_s *tx_desc, uint8_t *status) soc = pdev->soc; - DP_STATS_MSDU_INCR(soc, tx.inspect.pkts, tx_desc->nbuf); + DP_STATS_INC_PKT(pdev, tx.inspect_pkts, 1, + qdf_nbuf_len(tx_desc->nbuf)); DP_TX_FREE_SINGLE_BUF(soc, tx_desc->nbuf); } @@ -1150,8 +1174,9 @@ void dp_tx_process_htt_completion(struct dp_tx_desc_s *tx_desc, uint8_t *status) case HTT_TX_FW2WBM_TX_STATUS_TTL: { qdf_atomic_dec(&pdev->num_tx_exception); + DP_STATS_INC_PKT(pdev, tx.dropped.dropped_pkt, + 1, qdf_nbuf_len(tx_desc->nbuf)); DP_TX_FREE_SINGLE_BUF(soc, tx_desc->nbuf); - DP_STATS_MSDU_INCR(soc, tx.dropped.pkts, tx_desc->nbuf); break; } case HTT_TX_FW2WBM_TX_STATUS_REINJECT: @@ -1266,11 +1291,15 @@ static void dp_tx_comp_process_desc(struct dp_soc *soc, { struct dp_tx_desc_s *desc; struct dp_tx_desc_s *next; + struct hal_tx_completion_status ts = {0}; + uint32_t length; desc = comp_head; while (desc) { + hal_tx_comp_get_status(&desc->comp, &ts); + length = qdf_nbuf_len(desc->nbuf); /* Error Handling */ if (hal_tx_comp_get_buffer_source(&desc->comp) == HAL_TX_COMP_RELEASE_SOURCE_FW) { @@ -1307,6 +1336,13 @@ static void dp_tx_comp_process_desc(struct dp_soc *soc, DP_TX_FREE_DMA_TO_DEVICE(soc, desc->vdev, desc->nbuf); } + DP_STATS_INC_PKT(desc->pdev, tx.comp.comp_pkt, 1, + length); + DP_STATS_INCC(desc->pdev, tx.comp.mcs_count[MAX_MCS], 1, + ts.mcs >= MAX_MCS); + DP_STATS_INCC(desc->pdev, tx.comp.mcs_count[ts.mcs], 1, + ts.mcs <= MAX_MCS); + next = desc->next; dp_tx_desc_release(desc, desc->pool_id); desc = next; diff --git a/dp/wifi3.0/dp_tx.h b/dp/wifi3.0/dp_tx.h index ad2143b40697..fa1be7c7d2c2 100644 --- a/dp/wifi3.0/dp_tx.h +++ b/dp/wifi3.0/dp_tx.h @@ -22,9 +22,6 @@ #include #include "dp_types.h" -#define DP_STATS_ADD(x, y, z) -#define DP_STATS_SUB(x, y, z) -#define DP_STATS_MSDU_INCR(x, y, z) #define DP_TX_MAX_NUM_FRAGS 6 diff --git a/dp/wifi3.0/dp_tx_desc.h b/dp/wifi3.0/dp_tx_desc.h index 38f026a1b642..347c7e91dd43 100644 --- a/dp/wifi3.0/dp_tx_desc.h +++ b/dp/wifi3.0/dp_tx_desc.h @@ -21,6 +21,7 @@ #include "dp_types.h" #include "dp_tx.h" +#include "dp_internal.h" /** * 21 bits cookie @@ -74,7 +75,8 @@ static inline struct dp_tx_desc_s *dp_tx_desc_alloc(struct dp_soc *soc, soc->tx_desc[desc_pool_id].freelist->next; soc->tx_desc[desc_pool_id].num_allocated++; } - DP_STATS_ADD(pdev, pub.tx.desc_in_use, 1); + + DP_STATS_INC(soc, tx.desc_in_use, 1); tx_desc->flags = DP_TX_DESC_FLAG_ALLOCATED; TX_DESC_LOCK_UNLOCK(&soc->tx_desc[desc_pool_id].lock); @@ -98,7 +100,7 @@ dp_tx_desc_free(struct dp_soc *soc, struct dp_tx_desc_s *tx_desc, tx_desc->flags = 0; tx_desc->next = soc->tx_desc[desc_pool_id].freelist; soc->tx_desc[desc_pool_id].freelist = tx_desc; - DP_STATS_SUB(pdev, pub.tx.desc_in_use, 1); + DP_STATS_DEC(soc, tx.desc_in_use, 1); TX_DESC_LOCK_UNLOCK(&soc->tx_desc[desc_pool_id].lock); } diff --git a/dp/wifi3.0/dp_types.h b/dp/wifi3.0/dp_types.h index e712284bcdd9..0737038a0d12 100644 --- a/dp/wifi3.0/dp_types.h +++ b/dp/wifi3.0/dp_types.h @@ -36,6 +36,16 @@ #include #include #include "wlan_cfg.h" +#include "hal_rx.h" + +#define MAX_TCL_RING 3 +#define MAX_MCS 12 /* MCS rate varies from 0-11 */ +#define SS_COUNT 8 +#define MAX_RXDMA_ERRORS 32 +#define SUPPORTED_BW 4 +#define SUPPORTED_RECEPTION_TYPES 4 +#define RECEPTION_TYPE_MU_MIMO 1 +#define RECEPTION_TYPE_MU_OFDMA_MIMO 3 struct dp_soc_cmn; struct dp_pdev; @@ -61,11 +71,6 @@ union dp_rx_desc_list_elem_t; (_a)[4] == 0xff && \ (_a)[5] == 0xff) - -#define DP_TRACE(LVL, fmt, args ...) \ - QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_##LVL, \ - "%s:%d: "fmt, __func__, __LINE__, ## args) - /** * macros to convert hw mac id to sw mac id: * mac ids used by hardware start from a value of 1 while @@ -263,6 +268,116 @@ struct reo_desc_list_node { struct dp_rx_tid rx_tid; }; +/* TODO: Proper comments have been added in the subsequesnt gerrit */ +/* packet info */ +struct dp_pkt_info { + uint32_t num; /*no of packets*/ + uint32_t bytes; /* total no of bytes */ +}; + +/* per pdev tx stats*/ +struct dp_tx_pdev_stats { + + struct dp_pkt_info rcvd; /*total packets received for transmission */ + struct { + /* Pkt Info for which completions were received */ + struct dp_pkt_info comp_pkt; + uint32_t mcs_count[MAX_MCS + 1]; /* MCS Count */ + } comp; /* Tx completions received*/ + + struct dp_pkt_info freed; /* Tx packets freed*/ + + struct dp_pkt_info processed; /* Tx packets processed*/ + struct dp_pkt_info outstanding; /* Tx packets remaining for processing*/ + + struct { + struct dp_pkt_info dropped_pkt; /* Total packets dropped */ + uint32_t desc_total; /* total descriptors dropped */ + uint32_t dma_map_error; /* Dropped due to Dma Error */ + uint32_t ring_full; /* dropped due to ring full */ + uint32_t fw_discard; /* Discarded bu firmware */ + uint32_t fw_discard_retired; /* fw_discard_retired */ + /* firmware_discard_untransmitted */ + uint32_t firmware_discard_untransmitted; + uint32_t mpdu_age_out; /* mpdu_age_out */ + uint32_t firmware_discard_reason1; /*firmware_discard_reason1*/ + uint32_t firmware_discard_reason2; /*firmware_discard_reason2*/ + uint32_t firmware_discard_reason3; /*firmware_discard_reason3*/ + } dropped; /* Packets dropped on the Tx side */ + + struct { + struct dp_pkt_info sg_pkt; /* total scatter gather packets */ + uint32_t dropped_host; /* SG packets dropped by host */ + uint32_t dropped_target; /* SG packets dropped by target */ + } sg; /* Scatter Gather packet info */ + + struct { + uint32_t num_seg; /* No of segments in TSO packets */ + struct dp_pkt_info tso_pkt; /* total no of TSO packets */ + uint32_t dropped_host; /* TSO packets dropped by host */ + uint32_t dropped_target; /* TSO packets dropped by target */ + } tso; /* TSO packets info */ + + struct { + /* total no of multicast conversion packets */ + struct dp_pkt_info mcast_pkt; + /* packets dropped due to map error */ + uint32_t dropped_map_error; + /* packets dropped due to self Mac address */ + uint32_t dropped_self_mac; + /* Packets dropped due to send fail */ + uint32_t dropped_send_fail; + /* total unicast packets transmitted */ + uint32_t ucast; + } mcast_en; /* Multicast Enhancement packets info */ + + /* Total packets passed Reinject handler */ + struct dp_pkt_info reinject_pkts; + /* Total packets passed to inspect handler */ + struct dp_pkt_info inspect_pkts; + /* Total Raw packets */ + struct dp_pkt_info raw_pkt; +}; + +/* Per pdev RX stats */ +struct dp_rx_pdev_stats { + struct dp_pkt_info rcvd_reo; /* packets received on the reo ring */ + struct { + /* packets dropped because of no peer */ + struct dp_pkt_info no_peer; + /* packets dropped because nsdu_done bit not set */ + struct dp_pkt_info msdu_not_done; + } dropped; /* packets dropped on rx */ + struct dp_pkt_info replenished; /* total packets replnished */ + struct dp_pkt_info to_stack; /* total packets sent up the stack */ + struct dp_pkt_info intra_bss; /* Intra BSS packets received */ + struct dp_pkt_info wds; /* WDS packets received */ + struct dp_pkt_info desc; + struct dp_pkt_info buff; + struct dp_pkt_info raw; /* Raw Pakets received */ + struct { + uint32_t rxdma_unitialized; /* rxdma_unitialized errors */ + uint32_t desc_alloc_fail; /* desc alloc failed errors */ + } err; /* Rx errors */ + uint32_t buf_freelist; /* buffers added back in freelist */ + uint32_t mcs_count[MAX_MCS + 1]; /* packets in different MCS rates */ + uint32_t sgi_count[MAX_MCS + 1]; /* SGI count */ + /* Number of MSDUs with no MPDU level aggregation */ + uint32_t non_ampdu_cnt; + /* Number of MSDUs part of AMSPU */ + uint32_t ampdu_cnt; + /* Number of MSDUs with no MSDU level aggregation */ + uint32_t non_amsdu_cnt; + /* Number of MSDUs part of AMSDU*/ + uint32_t amsdu_cnt; + /* Packet count in spatiel Streams */ + uint32_t nss[SS_COUNT]; + /* Packet count in different Bandwidths */ + uint32_t bw[SUPPORTED_BW]; + /* reception type os packets */ + uint32_t reception_type[SUPPORTED_RECEPTION_TYPES]; +}; + /* SOC level structure for data path */ struct dp_soc { /* Common base structure - Should be the first member */ @@ -442,8 +557,31 @@ struct dp_soc { /* SoC level data path statistics */ struct { + struct { + /* descriptors in each tcl ring */ + uint32_t tcl_ring_full[MAX_TCL_RING]; + /* Descriptors in use at soc */ + uint32_t desc_in_use; + } tx; /* SOC level TX stats */ + struct { + struct { + /* Invalid RBM error count */ + uint32_t invalid_rbm; + /* Invalid VDEV Error count */ + uint32_t invalid_vdev; + /* Invalid PDEV error count */ + uint32_t invalid_pdev; + /* HAL ring access Fail error count */ + uint32_t hal_ring_access_fail; + /* RX DMA error count */ + uint32_t rxdma_error[MAX_RXDMA_ERRORS]; + /* REO Error count */ + uint32_t reo_error[ + HAL_REO_ERR_QUEUE_DESC_BLOCKED_SET+1]; + } err; /* Rx eerors */ + } rx; /* SOC level RX stats */ /* TBD */ - } stats; + } stats; /* TxRx SOC level stats */ /* Enable processing of Tx completion status words */ bool process_tx_status; @@ -520,6 +658,8 @@ struct dp_pdev { /* PDEV level data path statistics */ struct { + struct dp_tx_pdev_stats tx; /* per pdev tx stats */ + struct dp_rx_pdev_stats rx; /* per pdev rx stats */ /* TBD */ } stats; diff --git a/dp/wifi3.0/hal_rx.h b/dp/wifi3.0/hal_rx.h index 9320d025fc9c..e81d9ba69485 100644 --- a/dp/wifi3.0/hal_rx.h +++ b/dp/wifi3.0/hal_rx.h @@ -687,6 +687,58 @@ hal_rx_msdu_start_msdu_len_get(uint8_t *buf) return msdu_len; } +#define HAL_RX_MSDU_START_BW_GET(_rx_msdu_start) \ + (_HAL_MS((*_OFFSET_TO_WORD_PTR((_rx_msdu_start),\ + RX_MSDU_START_5_RECEIVE_BANDWIDTH_OFFSET)), \ + RX_MSDU_START_5_RECEIVE_BANDWIDTH_MASK, \ + RX_MSDU_START_5_RECEIVE_BANDWIDTH_LSB)) + +/* + * hal_rx_msdu_start_bw_get(): API to get the Bandwidth + * Interval from rx_msdu_start + * + * @buf: pointer to the start of RX PKT TLV header + * Return: uint32_t(bw) + */ +static inline uint32_t +hal_rx_msdu_start_bw_get(uint8_t *buf) +{ + struct rx_pkt_tlvs *pkt_tlvs = (struct rx_pkt_tlvs *)buf; + struct rx_msdu_start *msdu_start = + &pkt_tlvs->msdu_start_tlv.rx_msdu_start; + uint32_t bw; + + bw = HAL_RX_MSDU_START_BW_GET(msdu_start); + + return bw; +} + +#define HAL_RX_MSDU_START_RECEPTION_TYPE_GET(_rx_msdu_start) \ + (_HAL_MS((*_OFFSET_TO_WORD_PTR((_rx_msdu_start), \ + RX_MSDU_START_5_RECEPTION_TYPE_OFFSET)), \ + RX_MSDU_START_5_RECEPTION_TYPE_MASK, \ + RX_MSDU_START_5_RECEPTION_TYPE_LSB)) + +/* + * hal_rx_msdu_start_reception_type_get(): API to get the reception type + * Interval from rx_msdu_start + * + * @buf: pointer to the start of RX PKT TLV header + * Return: uint32_t(reception_type) + */ +static inline uint32_t +hal_rx_msdu_start_reception_type_get(uint8_t *buf) +{ + struct rx_pkt_tlvs *pkt_tlvs = (struct rx_pkt_tlvs *)buf; + struct rx_msdu_start *msdu_start = + &pkt_tlvs->msdu_start_tlv.rx_msdu_start; + uint32_t reception_type; + + reception_type = HAL_RX_MSDU_START_RECEPTION_TYPE_GET(msdu_start); + + return reception_type; +} + /* * Get qos_control_valid from RX_MPDU_START */