diff --git a/dp/inc/cdp_txrx_cmn.h b/dp/inc/cdp_txrx_cmn.h index 01b9ec57f7..0adcd4d712 100644 --- a/dp/inc/cdp_txrx_cmn.h +++ b/dp/inc/cdp_txrx_cmn.h @@ -494,17 +494,16 @@ static inline void cdp_flush_cache_rx_queue(ol_txrx_soc_handle soc) * cdp_txrx_stats(): function to map to host and firmware statistics * @soc: soc handle * @vdev: virtual device - * @req: statistics request handle * @stats: statistics option * * return: status */ static inline int cdp_txrx_stats(ol_txrx_soc_handle soc, struct cdp_vdev *vdev, - struct ol_txrx_stats_req *req, enum cdp_stats stats) + enum cdp_stats stats) { if (soc->ops->cmn_drv_ops->txrx_stats) - return soc->ops->cmn_drv_ops->txrx_stats(vdev, req, stats); + return soc->ops->cmn_drv_ops->txrx_stats(vdev, stats); return 0; } diff --git a/dp/inc/cdp_txrx_cmn_struct.h b/dp/inc/cdp_txrx_cmn_struct.h index 39a012d3a7..2a7d2c3f7b 100644 --- a/dp/inc/cdp_txrx_cmn_struct.h +++ b/dp/inc/cdp_txrx_cmn_struct.h @@ -130,11 +130,11 @@ enum htt_cmn_dbg_stats_type { */ enum cdp_host_txrx_stats { TXRX_HOST_STATS_INVALID = -1, - TXRX_RX_RATE_STATS = 0, - TXRX_TX_RATE_STATS = 1, - TXRX_TX_HOST_STATS = 2, - TXRX_RX_HOST_STATS = 3, - TXRX_CLEAR_STATS = 4, + TXRX_CLEAR_STATS = 0, + TXRX_RX_RATE_STATS = 1, + TXRX_TX_RATE_STATS = 2, + TXRX_TX_HOST_STATS = 3, + TXRX_RX_HOST_STATS = 4, TXRX_HOST_STATS_MAX, }; @@ -517,7 +517,8 @@ enum cdp_stats { CDP_TXRX_STATS_25, CDP_TXRX_STATS_26, CDP_TXRX_STATS_27, - CDP_TXRX_MAX_STATS, + CDP_TXRX_STATS_HTT_MAX = 256, + CDP_TXRX_MAX_STATS = 512, }; /* Different Packet Types */ diff --git a/dp/inc/cdp_txrx_host_stats.h b/dp/inc/cdp_txrx_host_stats.h index 43761285b4..94d7405b60 100644 --- a/dp/inc/cdp_txrx_host_stats.h +++ b/dp/inc/cdp_txrx_host_stats.h @@ -32,29 +32,36 @@ #ifndef _CDP_TXRX_HOST_STATS_H_ #define _CDP_TXRX_HOST_STATS_H_ #include "cdp_txrx_handle.h" -/* WIN */ -/* Need to remove the "req" parameter */ -/* 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, enum cdp_host_txrx_stats type) + struct cdp_vdev *vdev, + struct ol_txrx_stats_req *req) { if (soc->ops->host_stats_ops->txrx_host_stats_get) - return soc->ops->host_stats_ops->txrx_host_stats_get(vdev, req, - type); + return soc->ops->host_stats_ops->txrx_host_stats_get(vdev, req); return 0; } +/** + * cdp_host_stats_clr: cdp call to clear host stats + * @vdev: vdev handle + * + * return: void + */ +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,6 +220,15 @@ cdp_reset_lro_stats(ol_txrx_soc_handle soc, struct cdp_vdev *vdev) return; } +static inline void cdp_get_dp_fw_peer_stats(ol_txrx_soc_handle soc, + struct cdp_pdev *pdev, uint8_t *mac, uint32_t caps) +{ + if (soc->ops->host_stats_ops->get_fw_peer_stats) + return soc->ops->host_stats_ops->get_fw_peer_stats + (pdev, mac, caps); + 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 c230673950..8619b18e93 100644 --- a/dp/inc/cdp_txrx_ops.h +++ b/dp/inc/cdp_txrx_ops.h @@ -199,8 +199,7 @@ struct cdp_cmn_ops { void (*set_pdev_dscp_tid_map)(struct cdp_pdev *pdev, uint8_t map_id, uint8_t tos, uint8_t tid); - A_STATUS(*txrx_stats)(struct cdp_vdev *vdev, - struct ol_txrx_stats_req *req, enum cdp_stats stats); + int (*txrx_stats)(struct cdp_vdev *vdev, enum cdp_stats stats); QDF_STATUS (*display_stats)(void *psoc, uint16_t value); @@ -466,8 +465,9 @@ struct cdp_mon_ops { struct cdp_host_stats_ops { int (*txrx_host_stats_get)(struct cdp_vdev *vdev, - struct ol_txrx_stats_req *req, - enum cdp_host_txrx_stats type); + struct ol_txrx_stats_req *req); + + void (*txrx_host_stats_clr)(struct cdp_vdev *vdev); void (*txrx_host_ce_stats)(struct cdp_vdev *vdev); @@ -530,6 +530,10 @@ struct cdp_host_stats_ops { void (*reset_lro_stats)(struct cdp_vdev *vdev); + void + (*get_fw_peer_stats)(struct cdp_pdev *pdev, uint8_t *addr, + uint32_t cap); + }; struct cdp_wds_ops { diff --git a/dp/wifi3.0/dp_htt.c b/dp/wifi3.0/dp_htt.c index 7e5c541abf..f0c2aabbec 100644 --- a/dp/wifi3.0/dp_htt.c +++ b/dp/wifi3.0/dp_htt.c @@ -23,12 +23,16 @@ #include "dp_types.h" #include "dp_internal.h" #include "dp_rx_mon.h" +#include "htt_stats.h" + +#define HTT_TLV_HDR_LEN HTT_T2H_EXT_STATS_CONF_TLV_HDR_SIZE #define HTT_HTC_PKT_POOL_INIT_SIZE 64 #define HTT_MSG_BUF_SIZE(msg_bytes) \ ((msg_bytes) + HTC_HEADER_LEN + HTC_HDR_ALIGNMENT_PADDING) +#define DP_EXT_MSG_LENGTH 2048 /* * htt_htc_pkt_alloc() - Allocate HTC packet buffer * @htt_soc: HTT SOC handle @@ -853,6 +857,210 @@ fail0: return QDF_STATUS_E_FAILURE; } +/** + * dp_process_htt_stat_msg(): Process the list of buffers of HTT EXT stats + * @soc: DP SOC handle + * + * The FW sends the HTT EXT STATS as a stream of T2H messages. Each T2H message + * contains sub messages which are identified by a TLV header. + * In this function we will process the stream of T2H messages and read all the + * TLV contained in the message. + * + * THe following cases have been taken care of + * Case 1: When the tlv_remain_length <= msg_remain_length of HTT MSG buffer + * In this case the buffer will contain multiple tlvs. + * Case 2: When the tlv_remain_length > msg_remain_length of HTT MSG buffer. + * Only one tlv will be contained in the HTT message and this tag + * will extend onto the next buffer. + * Case 3: When the buffer is the continuation of the previous message + * Case 4: tlv length is 0. which will indicate the end of message + * + * return: void + */ +static inline void dp_process_htt_stat_msg(struct dp_soc *soc) +{ + htt_tlv_tag_t tlv_type = 0xff; + qdf_nbuf_t htt_msg = NULL; + uint32_t *msg_word; + uint8_t *tlv_buf_head = NULL; + uint8_t *tlv_buf_tail = NULL; + uint32_t msg_remain_len = 0; + uint32_t tlv_remain_len = 0; + uint32_t *tlv_start; + + /* Process node in the HTT message queue */ + while ((htt_msg = qdf_nbuf_queue_remove(&soc->htt_stats_msg)) != NULL) { + msg_word = (uint32_t *) qdf_nbuf_data(htt_msg); + /* read 5th word */ + msg_word = msg_word + 4; + msg_remain_len = qdf_min(soc->htt_msg_len, + (uint32_t)DP_EXT_MSG_LENGTH); + + /* Keep processing the node till node length is 0 */ + while (msg_remain_len) { + /* + * if message is not a continuation of previous message + * read the tlv type and tlv length + */ + if (!tlv_buf_head) { + tlv_type = HTT_STATS_TLV_TAG_GET( + *msg_word); + tlv_remain_len = HTT_STATS_TLV_LENGTH_GET( + *msg_word); + } + + if (tlv_remain_len == 0) { + msg_remain_len = 0; + + if (tlv_buf_head) { + qdf_mem_free(tlv_buf_head); + tlv_buf_head = NULL; + tlv_buf_tail = NULL; + } + + goto error; + } + + tlv_remain_len += HTT_TLV_HDR_LEN; + + if ((tlv_remain_len <= msg_remain_len)) { + /* Case 3 */ + if (tlv_buf_head) { + qdf_mem_copy(tlv_buf_tail, + (uint8_t *)msg_word, + tlv_remain_len); + tlv_start = (uint32_t *)tlv_buf_head; + } else { + /* Case 1 */ + tlv_start = msg_word; + } + + dp_htt_stats_print_tag(tlv_type, tlv_start); + + msg_remain_len -= tlv_remain_len; + + msg_word = (uint32_t *) + (((uint8_t *)msg_word) + + tlv_remain_len); + + tlv_remain_len = 0; + + if (tlv_buf_head) { + qdf_mem_free(tlv_buf_head); + tlv_buf_head = NULL; + tlv_buf_tail = NULL; + } + + } else { /* tlv_remain_len > msg_remain_len */ + /* Case 2 & 3 */ + if (!tlv_buf_head) { + tlv_buf_head = qdf_mem_malloc( + tlv_remain_len); + + if (!tlv_buf_head) { + QDF_TRACE(QDF_MODULE_ID_TXRX, + QDF_TRACE_LEVEL_ERROR, + "Alloc failed"); + goto error; + } + + tlv_buf_tail = tlv_buf_head; + } + + qdf_mem_copy(tlv_buf_tail, (uint8_t *)msg_word, + msg_remain_len); + tlv_remain_len -= msg_remain_len; + tlv_buf_tail += msg_remain_len; + msg_remain_len = 0; + } + } + + if (soc->htt_msg_len >= DP_EXT_MSG_LENGTH) { + soc->htt_msg_len -= DP_EXT_MSG_LENGTH; + } + + qdf_nbuf_free(htt_msg); + } + soc->htt_msg_len = 0; + return; + +error: + qdf_nbuf_free(htt_msg); + soc->htt_msg_len = 0; + while ((htt_msg = qdf_nbuf_queue_remove(&soc->htt_stats_msg)) + != NULL) + qdf_nbuf_free(htt_msg); +} + +/** + * dp_txrx_fw_stats_handler():Function to process HTT EXT stats + * @soc: DP SOC handle + * @htt_t2h_msg: HTT message nbuf + * + * return:void + */ +static inline void dp_txrx_fw_stats_handler(struct dp_soc *soc, + qdf_nbuf_t htt_t2h_msg) +{ + uint32_t length; + uint8_t done; + qdf_nbuf_t msg_copy; + uint32_t *msg_word; + + msg_word = (uint32_t *) qdf_nbuf_data(htt_t2h_msg); + msg_word = msg_word + 3; + done = 0; + length = HTT_T2H_EXT_STATS_CONF_TLV_LENGTH_GET(*msg_word); + done = HTT_T2H_EXT_STATS_CONF_TLV_DONE_GET(*msg_word); + + /* + * HTT EXT stats response comes as stream of TLVs which span over + * multiple T2H messages. + * The first message will carry length of the response. + * For rest of the messages length will be zero. + */ + if (soc->htt_msg_len && length) + goto error; + + if (length) + soc->htt_msg_len = length; + + /* + * Clone the T2H message buffer and store it in a list to process + * it later. + * + * The original T2H message buffers gets freed in the T2H HTT event + * handler + */ + msg_copy = qdf_nbuf_clone(htt_t2h_msg); + + if (!msg_copy) { + QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_INFO, + "T2H messge clone failed for HTT EXT STATS"); + soc->htt_msg_len = 0; + goto error; + } + + qdf_nbuf_queue_add(&soc->htt_stats_msg, msg_copy); + + /* + * Done bit signifies that this is the last T2H buffer in the stream of + * HTT EXT STATS message + */ + if (done) + dp_process_htt_stat_msg(soc); + + return; + +error: + while ((msg_copy = qdf_nbuf_queue_remove(&soc->htt_stats_msg)) + != NULL) { + qdf_nbuf_free(msg_copy); + } + return; + +} + /* * htt_soc_attach_target() - SOC level HTT setup * @htt_soc: HTT SOC handle @@ -1015,8 +1223,11 @@ static void dp_htt_t2h_msg_handler(void *context, HTC_PACKET *pkt) } break; } - - + case HTT_T2H_MSG_TYPE_EXT_STATS_CONF: + { + dp_txrx_fw_stats_handler(soc->dp_soc, htt_t2h_msg); + break; + } default: break; }; @@ -1166,3 +1377,100 @@ htt_soc_detach(void *htt_soc) qdf_mem_free(soc); } +/** + * dp_h2t_ext_stats_msg_send(): function to contruct HTT message to pass to FW + * @pdev: DP PDEV handle + * @stats_type_upload_mask: stats type requested by user + * @config_param_0: extra configuration parameters + * @config_param_1: extra configuration parameters + * @config_param_2: extra configuration parameters + * @config_param_3: extra configuration parameters + * + * return: QDF STATUS + */ +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) +{ + struct htt_soc *soc = pdev->soc->htt_handle; + struct dp_htt_htc_pkt *pkt; + qdf_nbuf_t msg; + uint32_t *msg_word; + uint8_t pdev_mask; + + msg = qdf_nbuf_alloc( + soc->osdev, + HTT_MSG_BUF_SIZE(HTT_H2T_EXT_STATS_REQ_MSG_SZ), + HTC_HEADER_LEN + HTC_HDR_ALIGNMENT_PADDING, 4, TRUE); + + if (!msg) + return QDF_STATUS_E_NOMEM; + + /*TODO:Add support for SOC stats + * Bit 0: SOC Stats + * Bit 1: Pdev stats for pdev id 0 + * Bit 2: Pdev stats for pdev id 1 + * Bit 3: Pdev stats for pdev id 2 + */ + pdev_mask = 1 << (pdev->pdev_id + 1); + + /* + * Set the length of the message. + * The contribution from the HTC_HDR_ALIGNMENT_PADDING is added + * separately during the below call to qdf_nbuf_push_head. + * The contribution from the HTC header is added separately inside HTC. + */ + if (qdf_nbuf_put_tail(msg, HTT_H2T_EXT_STATS_REQ_MSG_SZ) == NULL) { + QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_ERROR, + "Failed to expand head for HTT_EXT_STATS"); + qdf_nbuf_free(msg); + return QDF_STATUS_E_FAILURE; + } + + msg_word = (uint32_t *) qdf_nbuf_data(msg); + + qdf_nbuf_push_head(msg, HTC_HDR_ALIGNMENT_PADDING); + *msg_word = 0; + HTT_H2T_MSG_TYPE_SET(*msg_word, HTT_H2T_MSG_TYPE_EXT_STATS_REQ); + HTT_H2T_EXT_STATS_REQ_PDEV_MASK_SET(*msg_word, pdev_mask); + HTT_H2T_EXT_STATS_REQ_STATS_TYPE_SET(*msg_word, stats_type_upload_mask); + + /* word 1 */ + msg_word++; + *msg_word = 0; + HTT_H2T_EXT_STATS_REQ_CONFIG_PARAM_SET(*msg_word, config_param_0); + + /* word 2 */ + msg_word++; + *msg_word = 0; + HTT_H2T_EXT_STATS_REQ_CONFIG_PARAM_SET(*msg_word, config_param_1); + + /* word 3 */ + msg_word++; + *msg_word = 0; + HTT_H2T_EXT_STATS_REQ_CONFIG_PARAM_SET(*msg_word, config_param_2); + + /* word 4 */ + msg_word++; + *msg_word = 0; + HTT_H2T_EXT_STATS_REQ_CONFIG_PARAM_SET(*msg_word, config_param_3); + + HTT_H2T_EXT_STATS_REQ_CONFIG_PARAM_SET(*msg_word, 0); + pkt = htt_htc_pkt_alloc(soc); + if (!pkt) { + qdf_nbuf_free(msg); + return QDF_STATUS_E_NOMEM; + } + + pkt->soc_ctxt = NULL; /* not used during send-done callback */ + + SET_HTC_PACKET_INFO_TX(&pkt->htc_pkt, + dp_htt_h2t_send_complete_free_netbuf, + qdf_nbuf_data(msg), qdf_nbuf_len(msg), + soc->htc_endpoint, + 1); /* tag - not relevant here */ + + SET_HTC_PACKET_NET_BUF_CONTEXT(&pkt->htc_pkt, msg); + return htc_send_pkt(soc->htc_soc, &pkt->htc_pkt); +} diff --git a/dp/wifi3.0/dp_internal.h b/dp/wifi3.0/dp_internal.h index 2ee1e43a31..383c004d71 100644 --- a/dp/wifi3.0/dp_internal.h +++ b/dp/wifi3.0/dp_internal.h @@ -279,4 +279,9 @@ uint16_t dp_tx_me_send_convert_ucast(struct cdp_vdev *vdev_handle, void dp_tx_me_alloc_descriptor(struct cdp_pdev *pdev); 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); +void dp_htt_stats_print_tag(uint8_t tag_type, uint32_t *tag_buf); #endif /* #ifndef _DP_INTERNAL_H_ */ diff --git a/dp/wifi3.0/dp_main.c b/dp/wifi3.0/dp_main.c index fcae516b3a..dc1d12853e 100644 --- a/dp/wifi3.0/dp_main.c +++ b/dp/wifi3.0/dp_main.c @@ -36,12 +36,15 @@ #include #include "dp_peer.h" #include "dp_rx_mon.h" +#include "htt_stats.h" #define DP_INTR_POLL_TIMER_MS 10 #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*REO_ERROR_TYPE_MAX) +#define DP_CURR_FW_STATS_AVAIL 19 +#define DP_HTT_DBG_EXT_STATS_MAX 256 /** * default_dscp_tid_map - Default DSCP-TID mapping @@ -89,33 +92,31 @@ enum dp_fw_stats { * currently supported */ const int dp_stats_mapping_table[][STATS_TYPE_MAX] = { + {HTT_DBG_EXT_STATS_RESET, TXRX_HOST_STATS_INVALID}, + {HTT_DBG_EXT_STATS_PDEV_TX, TXRX_HOST_STATS_INVALID}, + {HTT_DBG_EXT_STATS_PDEV_RX, TXRX_HOST_STATS_INVALID}, + {HTT_DBG_EXT_STATS_PDEV_TX_HWQ, TXRX_HOST_STATS_INVALID}, + {HTT_DBG_EXT_STATS_PDEV_TX_SCHED, TXRX_HOST_STATS_INVALID}, + {HTT_DBG_EXT_STATS_PDEV_ERROR, TXRX_HOST_STATS_INVALID}, + {HTT_DBG_EXT_STATS_PDEV_TQM, TXRX_HOST_STATS_INVALID}, + {HTT_DBG_EXT_STATS_TQM_CMDQ, TXRX_HOST_STATS_INVALID}, + {HTT_DBG_EXT_STATS_TX_DE_INFO, TXRX_HOST_STATS_INVALID}, + {HTT_DBG_EXT_STATS_PDEV_TX_RATE, TXRX_HOST_STATS_INVALID}, + {HTT_DBG_EXT_STATS_PDEV_RX_RATE, TXRX_HOST_STATS_INVALID}, {TXRX_FW_STATS_INVALID, TXRX_HOST_STATS_INVALID}, - {TXRX_FW_STATS_INVALID, TXRX_HOST_STATS_INVALID}, - {TXRX_FW_STATS_INVALID, TXRX_HOST_STATS_INVALID}, - {TXRX_FW_STATS_INVALID, TXRX_RX_RATE_STATS}, - {TXRX_FW_STATS_INVALID, TXRX_HOST_STATS_INVALID}, - {TXRX_FW_STATS_INVALID, TXRX_HOST_STATS_INVALID}, - {TXRX_FW_STATS_INVALID, TXRX_TX_RATE_STATS}, - {TXRX_FW_STATS_INVALID, TXRX_HOST_STATS_INVALID}, - {TXRX_FW_STATS_INVALID, TXRX_TX_HOST_STATS}, + {HTT_DBG_EXT_STATS_TX_SELFGEN_INFO, TXRX_HOST_STATS_INVALID}, + {HTT_DBG_EXT_STATS_TX_MU_HWQ, TXRX_HOST_STATS_INVALID}, + {HTT_DBG_EXT_STATS_RING_IF_INFO, TXRX_HOST_STATS_INVALID}, + {HTT_DBG_EXT_STATS_SRNG_INFO, TXRX_HOST_STATS_INVALID}, + {HTT_DBG_EXT_STATS_SFM_INFO, TXRX_HOST_STATS_INVALID}, + {HTT_DBG_EXT_STATS_PDEV_TX_MU, TXRX_HOST_STATS_INVALID}, + {HTT_DBG_EXT_STATS_ACTIVE_PEERS_LIST, TXRX_HOST_STATS_INVALID}, + /* Last ENUM for HTT FW STATS */ + {DP_HTT_DBG_EXT_STATS_MAX, TXRX_HOST_STATS_INVALID}, {TXRX_FW_STATS_INVALID, TXRX_CLEAR_STATS}, - {TXRX_FW_STATS_INVALID, TXRX_HOST_STATS_INVALID}, - {TXRX_FW_STATS_INVALID, TXRX_HOST_STATS_INVALID}, - {TXRX_FW_STATS_INVALID, TXRX_HOST_STATS_INVALID}, - {TXRX_FW_STATS_INVALID, TXRX_HOST_STATS_INVALID}, - {TXRX_FW_STATS_INVALID, TXRX_HOST_STATS_INVALID}, - {TXRX_FW_STATS_INVALID, TXRX_HOST_STATS_INVALID}, - {TXRX_FW_STATS_INVALID, TXRX_HOST_STATS_INVALID}, - {TXRX_FW_STATS_INVALID, TXRX_HOST_STATS_INVALID}, - {TXRX_FW_STATS_INVALID, TXRX_HOST_STATS_INVALID}, - {TXRX_FW_STATS_INVALID, TXRX_HOST_STATS_INVALID}, - {TXRX_FW_STATS_INVALID, TXRX_HOST_STATS_INVALID}, - {TXRX_FW_STATS_INVALID, TXRX_HOST_STATS_INVALID}, - {TXRX_FW_STATS_INVALID, TXRX_HOST_STATS_INVALID}, - {TXRX_FW_STATS_INVALID, TXRX_HOST_STATS_INVALID}, - {TXRX_FW_STATS_INVALID, TXRX_HOST_STATS_INVALID}, - {TXRX_FW_STATS_INVALID, TXRX_HOST_STATS_INVALID}, - {TXRX_FW_STATS_INVALID, TXRX_HOST_STATS_INVALID}, + {TXRX_FW_STATS_INVALID, TXRX_RX_RATE_STATS}, + {TXRX_FW_STATS_INVALID, TXRX_TX_RATE_STATS}, + {TXRX_FW_STATS_INVALID, TXRX_TX_HOST_STATS}, {TXRX_FW_STATS_INVALID, TXRX_RX_HOST_STATS}, }; @@ -975,6 +976,7 @@ static int dp_soc_cmn_setup(struct dp_soc *soc) hal_reo_setup(soc->hal_soc, &reo_params); qdf_atomic_set(&soc->cmn_init_done, 1); + qdf_nbuf_queue_init(&soc->htt_stats_msg); return 0; fail1: /* @@ -3289,27 +3291,28 @@ static inline void dp_print_peer_stats(struct dp_peer *peer) /** * 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_CLEAR_STATS : Clear the stats * 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, print error message in case of failure */ static int -dp_print_host_stats(struct cdp_vdev *vdev_handle, struct ol_txrx_stats_req *req, - enum cdp_host_txrx_stats type) +dp_print_host_stats(struct cdp_vdev *vdev_handle, enum cdp_host_txrx_stats type) { struct dp_vdev *vdev = (struct dp_vdev *)vdev_handle; struct dp_pdev *pdev = (struct dp_pdev *)vdev->pdev; dp_aggregate_pdev_stats(pdev); switch (type) { + case TXRX_CLEAR_STATS: + dp_txrx_host_stats_clr(vdev); + break; case TXRX_RX_RATE_STATS: dp_print_rx_rates(vdev); break; @@ -3324,9 +3327,6 @@ dp_print_host_stats(struct cdp_vdev *vdev_handle, struct ol_txrx_stats_req *req, 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: DP_TRACE(FATAL, "Wrong Input For TxRx Host Stats"); break; @@ -3335,23 +3335,65 @@ dp_print_host_stats(struct cdp_vdev *vdev_handle, struct ol_txrx_stats_req *req, } /* - * dp_get_peer_stats()- function to print peer stats + * dp_get_host_peer_stats()- function to print peer stats * @pdev_handle: DP_PDEV handle * @mac_addr: mac address of the peer * * Return: void */ static void -dp_get_peer_stats(struct cdp_pdev *pdev_handle, char *mac_addr) +dp_get_host_peer_stats(struct cdp_pdev *pdev_handle, char *mac_addr) { struct dp_peer *peer; uint8_t local_id; peer = (struct dp_peer *)dp_find_peer_by_addr(pdev_handle, mac_addr, &local_id); - dp_print_peer_stats(peer); - return; + dp_print_peer_stats(peer); + return; } + +/* + * dp_get_fw_peer_stats()- function to print peer stats + * @pdev_handle: DP_PDEV handle + * @mac_addr: mac address of the peer + * @cap: Type of htt stats requested + * + * Currently Supporting only MAC ID based requests Only + * 1: HTT_PEER_STATS_REQ_MODE_NO_QUERY + * 2: HTT_PEER_STATS_REQ_MODE_QUERY_TQM + * 3: HTT_PEER_STATS_REQ_MODE_FLUSH_TQM + * + * Return: void + */ +static void +dp_get_fw_peer_stats(struct cdp_pdev *pdev_handle, uint8_t *mac_addr, + uint32_t cap) +{ + struct dp_pdev *pdev = (struct dp_pdev *)pdev_handle; + uint32_t config_param0 = 0; + uint32_t config_param1 = 0; + uint32_t config_param2 = 0; + uint32_t config_param3 = 0; + + HTT_DBG_EXT_STATS_PEER_INFO_IS_MAC_ADDR_SET(config_param0, 1); + config_param0 |= (1 << (cap + 1)); + + config_param1 = 0x8f; + + config_param2 |= (mac_addr[0] & 0x000000ff); + config_param2 |= ((mac_addr[1] << 8) & 0x0000ff00); + config_param2 |= ((mac_addr[2] << 16) & 0x00ff0000); + config_param2 |= ((mac_addr[3] << 24) & 0xff000000); + + 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); +} + /* * dp_set_vdev_param: function to set parameters in vdev * @param: parameter type to be set @@ -3436,16 +3478,35 @@ static void dp_set_pdev_dscp_tid_map_wifi3(struct cdp_pdev *pdev_handle, return; } +/** + * dp_fw_stats_process(): Process TxRX FW stats request + * @vdev_handle: DP VDEV handle + * @val: value passed by user + * + * return: int + */ +static int dp_fw_stats_process(struct cdp_vdev *vdev_handle, uint32_t val) +{ + struct dp_vdev *vdev = (struct dp_vdev *)vdev_handle; + struct dp_pdev *pdev = NULL; + + if (!vdev) { + DP_TRACE(NONE, "VDEV not found"); + return 1; + } + + pdev = vdev->pdev; + return dp_h2t_ext_stats_msg_send(pdev, val, 0, 0, 0, 0); +} + /* * dp_txrx_stats() - function to map to firmware and host stats * @vdev: virtual handle - * @req: statistics request handle * @stats: type of statistics requested * * Return: integer */ -static int dp_txrx_stats(struct cdp_vdev *vdev, - struct ol_txrx_stats_req *req, enum cdp_stats stats) +static int dp_txrx_stats(struct cdp_vdev *vdev, enum cdp_stats stats) { int host_stats; int fw_stats; @@ -3453,6 +3514,12 @@ static int dp_txrx_stats(struct cdp_vdev *vdev, if (stats >= CDP_TXRX_MAX_STATS) return 0; + /* + * DP_CURR_FW_STATS_AVAIL: no of FW stats currently available + * has to be updated if new FW HTT stats added + */ + if (stats > CDP_TXRX_STATS_HTT_MAX) + stats = stats + DP_CURR_FW_STATS_AVAIL - DP_HTT_DBG_EXT_STATS_MAX; fw_stats = dp_stats_mapping_table[stats][STATS_FW]; host_stats = dp_stats_mapping_table[stats][STATS_HOST]; @@ -3460,11 +3527,12 @@ static int dp_txrx_stats(struct cdp_vdev *vdev, "stats: %u fw_stats_type: %d host_stats_type: %d", stats, fw_stats, host_stats); - /* TODO: Firmware Mapping not implemented */ + if (fw_stats != TXRX_FW_STATS_INVALID) + return dp_fw_stats_process(vdev, fw_stats); if ((host_stats != TXRX_HOST_STATS_INVALID) && (host_stats <= TXRX_HOST_STATS_MAX)) - return dp_print_host_stats(vdev, req, host_stats); + return dp_print_host_stats(vdev, host_stats); else QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_INFO, "Wrong Input for TxRx Stats"); @@ -3751,8 +3819,8 @@ 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, - .txrx_per_peer_stats = dp_get_peer_stats, + .txrx_per_peer_stats = dp_get_host_peer_stats, + .get_fw_peer_stats = dp_get_fw_peer_stats, /* TODO */ }; diff --git a/dp/wifi3.0/dp_stats.c b/dp/wifi3.0/dp_stats.c new file mode 100644 index 0000000000..48594841ac --- /dev/null +++ b/dp/wifi3.0/dp_stats.c @@ -0,0 +1,262 @@ +/* + * Copyright (c) 2017 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 + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ +#include "qdf_types.h" +#include "htt_stats.h" +#include "dp_types.h" +#include "dp_internal.h" + +#define DP_MAX_STRING_LEN 500 + +/* these values are fixed in the next gerrit */ +#define DP_HTT_DATA_LEN 1 +#define DP_HTT_URRN_STATS_LEN 1 +#define DP_HTT_FLUSH_ERRS_LEN 1 +#define DP_HTT_SIFS_STATUS_LEN 1 +#define DP_HTT_PHY_ERRS_LEN 1 +#define DP_HTT_HW_INTR_NAME_LEN HTT_STATS_MAX_HW_INTR_NAME_LEN +#define DP_HTT_HW_MODULE_NAME_LEN HTT_STATS_MAX_HW_MODULE_NAME_LEN +#define DP_HTT_COUNTER_NAME_LEN HTT_MAX_COUNTER_NAME +#define DP_HTT_PEER_DETAILS_LEN 1 +#define DP_HTT_MU_MIMO_SCH_STATS_TLV_LEN 1 +#define DP_HTT_MU_MIMO_MPDU_STATS_TLV_LEN 1 +#define DP_HTT_DIFS_LATENCY_HIST_LEN 1 +#define DP_HTT_CMD_RESULT_LEN 1 +#define DP_HTT_CMD_STALL_STATUS_LEN 1 +#define DP_HTT_FES_RESULT_LEN 1 +#define DP_HTT_SCHED_CMD_POSTED_LEN 1 +#define DP_HTT_SCHED_CMD_REAPED_LEN 1 +#define DP_HTT_GEN_MPDU_END_REASON_LEN 1 +#define DP_HTT_LIST_MPDU_END_REASON_LEN 1 +#define DP_HTT_LIST_MPDU_CNT_HIST_LEN 1 +#define DP_HTT_LOW_WM_HIT_COUNT_LEN HTT_STATS_LOW_WM_BINS +#define DP_HTT_HIGH_WM_HIT_COUNT_LEN HTT_STATS_HIGH_WM_BINS +#define DP_HTT_DWORDS_USED_BY_USER_N_LEN 1 +#define DP_HTT_TX_MCS_LEN HTT_TX_PDEV_STATS_NUM_MCS_COUNTERS +#define DP_HTT_TX_SU_MCS_LEN HTT_TX_PDEV_STATS_NUM_MCS_COUNTERS +#define DP_HTT_TX_MU_MCS_LEN HTT_TX_PDEV_STATS_NUM_MCS_COUNTERS +#define DP_HTT_TX_NSS_LEN HTT_TX_PDEV_STATS_NUM_SPATIAL_STREAMS +#define DP_HTT_TX_BW_LEN HTT_TX_PDEV_STATS_NUM_BW_COUNTERS +#define DP_HTT_TX_STBC_LEN HTT_TX_PDEV_STATS_NUM_MCS_COUNTERS +#define DP_HTT_TX_PREAM_LEN HTT_TX_PDEV_STATS_NUM_PREAMBLE_TYPES +#define DP_HTT_TX_GI_LEN HTT_TX_PDEV_STATS_NUM_GI_COUNTERS +#define DP_HTT_TX_DCM_LEN HTT_TX_PDEV_STATS_NUM_DCM_COUNTERS +#define DP_HTT_RX_MCS_LEN HTT_RX_PDEV_STATS_NUM_MCS_COUNTERS +#define DP_HTT_RX_NSS_LEN HTT_RX_PDEV_STATS_NUM_SPATIAL_STREAMS +#define DP_HTT_RX_DCM_LEN HTT_RX_PDEV_STATS_NUM_DCM_COUNTERS +#define DP_HTT_RX_STBC_LEN HTT_RX_PDEV_STATS_NUM_MCS_COUNTERS +#define DP_HTT_RX_BW_LEN HTT_RX_PDEV_STATS_NUM_BW_COUNTERS +#define DP_HTT_RX_PREAM_LEN HTT_RX_PDEV_STATS_NUM_PREAMBLE_TYPES +#define DP_HTT_RSSI_CHAIN_LEN HTT_RX_PDEV_STATS_NUM_SPATIAL_STREAMS +#define DP_HTT_RX_GI_LEN HTT_RX_PDEV_STATS_NUM_GI_COUNTERS +#define DP_HTT_REFILL_RING_EMPTY_CNT_LEN 1 +#define DP_HTT_REFILL_RING_NUM_REFILL_LEN 1 +#define DP_HTT_FW_RING_MGMT_SUBTYPE_LEN HTT_STATS_SUBTYPE_MAX +#define DP_HTT_FW_RING_CTRL_SUBTYPE_LEN HTT_STATS_SUBTYPE_MAX +#define DP_HTT_FW_RING_MPDU_ERR_LEN HTT_RX_STATS_RXDMA_MAX_ERR +#define DP_HTT_FW_MPDU_DROP_LEN 1 +#define DP_HTT_TID_NAME_LEN MAX_HTT_TID_NAME + +/* TODO:Below stat function is for initial testing + * Further functions will be added after reviews on the FW side are complete + */ + +/** + * dp_print_tx_pdev_stats_cmn_tlv: display htt_tx_pdev_stats_cmn_tlv + * @dp_htt_tag:pointer to structure htt_tx_pdev_stats_cmn_tlv + * + * return:void + */ +static inline void dp_print_tx_pdev_stats_cmn_tlv(uint32_t *tag_buf) +{ + htt_tx_pdev_stats_cmn_tlv *dp_htt_tag = + (htt_tx_pdev_stats_cmn_tlv *)tag_buf; + + DP_TRACE_STATS(NONE, "Pdev Stats:\n"); + DP_TRACE_STATS(NONE, "mac_id__word = %d", + dp_htt_tag->mac_id__word); + DP_TRACE_STATS(NONE, "hw_queued = %d", + dp_htt_tag->hw_queued); + DP_TRACE_STATS(NONE, "hw_reaped = %d", + dp_htt_tag->hw_reaped); + DP_TRACE_STATS(NONE, "underrun = %d", + dp_htt_tag->underrun); + DP_TRACE_STATS(NONE, "hw_paused = %d", + dp_htt_tag->hw_paused); + DP_TRACE_STATS(NONE, "hw_flush = %d", + dp_htt_tag->hw_flush); + DP_TRACE_STATS(NONE, "hw_filt = %d", + dp_htt_tag->hw_filt); + DP_TRACE_STATS(NONE, "tx_abort = %d", + dp_htt_tag->tx_abort); + DP_TRACE_STATS(NONE, "mpdu_requeued = %d", + dp_htt_tag->mpdu_requed); + DP_TRACE_STATS(NONE, "tx_xretry = %d", + dp_htt_tag->tx_xretry); + DP_TRACE_STATS(NONE, "data_rc = %d", + dp_htt_tag->data_rc); + DP_TRACE_STATS(NONE, "mpdu_dropped_xretry = %d", + dp_htt_tag->mpdu_dropped_xretry); + DP_TRACE_STATS(NONE, "illegal_rate_phy_err = %d", + dp_htt_tag->illgl_rate_phy_err); + DP_TRACE_STATS(NONE, "cont_xretry = %d", + dp_htt_tag->cont_xretry); + DP_TRACE_STATS(NONE, "tx_timeout = %d", + dp_htt_tag->tx_timeout); + DP_TRACE_STATS(NONE, "pdev_resets = %d", + dp_htt_tag->pdev_resets); + DP_TRACE_STATS(NONE, "phy_underrun = %d", + dp_htt_tag->phy_underrun); + DP_TRACE_STATS(NONE, "txop_ovf = %d", + dp_htt_tag->txop_ovf); + DP_TRACE_STATS(NONE, "seq_posted = %d", + dp_htt_tag->seq_posted); + DP_TRACE_STATS(NONE, "seq_failed_queueing = %d", + dp_htt_tag->seq_failed_queueing); + DP_TRACE_STATS(NONE, "seq_completed = %d", + dp_htt_tag->seq_completed); + DP_TRACE_STATS(NONE, "seq_restarted = %d", + dp_htt_tag->seq_restarted); + DP_TRACE_STATS(NONE, "mu_seq_posted = %d", + dp_htt_tag->mu_seq_posted); + DP_TRACE_STATS(NONE, "mpdu_count_tqm = %d", + dp_htt_tag->mpdu_count_tqm); + DP_TRACE_STATS(NONE, "msdu_count_tqm = %d", + dp_htt_tag->msdu_count_tqm); + DP_TRACE_STATS(NONE, "mpdu_removed_tqm = %d", + dp_htt_tag->mpdu_removed_tqm); + DP_TRACE_STATS(NONE, "msdu_removed_tqm = %d", + dp_htt_tag->msdu_removed_tqm); + DP_TRACE_STATS(NONE, "mpdus_sw_flush = %d", + dp_htt_tag->mpdus_sw_flush); + DP_TRACE_STATS(NONE, "mpdus_hw_filter = %d", + dp_htt_tag->mpdus_hw_filter); + DP_TRACE_STATS(NONE, "mpdus_truncated = %d", + dp_htt_tag->mpdus_truncated); + DP_TRACE_STATS(NONE, "mpdus_ack_failed = %d", + dp_htt_tag->mpdus_ack_failed); + DP_TRACE_STATS(NONE, "mpdus_expired = %d", + dp_htt_tag->mpdus_expired); + DP_TRACE_STATS(NONE, "mpdus_seq_hw_retry = %d", + dp_htt_tag->mpdus_seq_hw_retry); + DP_TRACE_STATS(NONE, "ack_tlv_proc = %d", + dp_htt_tag->ack_tlv_proc); + DP_TRACE_STATS(NONE, "coex_abort_mpdu_cnt_valid = %d", + dp_htt_tag-> + coex_abort_mpdu_cnt_valid); + DP_TRACE_STATS(NONE, "coex_abort_mpdu_cnt = %d", + dp_htt_tag->coex_abort_mpdu_cnt); +} + +/** + * dp_print_tx_pdev_stats_urrn_tlv_v: display htt_tx_pdev_stats_urrn_tlv_v + * @tag_buf: buffer containing the tlv + * + * return:void + */ +static inline void dp_print_tx_pdev_stats_urrn_tlv_v(uint32_t *tag_buf) +{ + htt_tx_pdev_stats_urrn_tlv_v *dp_htt_tag = + (htt_tx_pdev_stats_urrn_tlv_v *)tag_buf; + uint8_t i; + uint16_t index = 0; + char urrn_stats[DP_MAX_STRING_LEN]; + uint32_t tag_len = (HTT_STATS_TLV_LENGTH_GET(*tag_buf) >> 2); + + tag_len = qdf_min(tag_len, (uint32_t)HTT_TX_PDEV_MAX_URRN_STATS); + DP_TRACE_STATS(NONE, "Pdev Underun Stats:\n"); + for (i = 0; i < tag_len; i++) { + index += qdf_snprint(&urrn_stats[index], + DP_MAX_STRING_LEN - index, " %d,", + dp_htt_tag->urrn_stats[i]); + } + DP_TRACE_STATS(NONE, "urrn_stats = %s", urrn_stats); +} + +/* + * dp_print_tx_pdev_stats_flush_tlv_v: display htt_tx_pdev_stats_flush_tlv_v + * @tag_buf: buffer containing the tlv * + * return:void + */ +static inline void dp_print_tx_pdev_stats_flush_tlv_v(uint32_t *tag_buf) +{ + htt_tx_pdev_stats_flush_tlv_v *dp_htt_tag = + (htt_tx_pdev_stats_flush_tlv_v *)tag_buf; + uint8_t i; + uint8_t index = 0; + char flush_errs[DP_MAX_STRING_LEN]; + uint32_t tag_len = (HTT_STATS_TLV_LENGTH_GET(*tag_buf) >> 2); + + tag_len = qdf_min(tag_len, + (uint32_t)HTT_TX_PDEV_MAX_FLUSH_REASON_STATS); + DP_TRACE_STATS(NONE, "Pdev Flush Stats:\n"); + for (i = 0; i < tag_len; i++) { + index += qdf_snprint(&flush_errs[index], + DP_MAX_STRING_LEN - index, " %d,", + dp_htt_tag->flush_errs[i]); + } + DP_TRACE_STATS(NONE, "flush_errs = %s ", flush_errs); +} + +/* + * dp_print_tx_pdev_stats_sifs_tlv_v: display htt_tx_pdev_stats_sifs_tlv_v + * @tag_buf: buffer containing the tlv * + * return:void + */ +static inline void dp_print_tx_pdev_stats_sifs_tlv_v(uint32_t *tag_buf) +{ + htt_tx_pdev_stats_sifs_tlv_v *dp_htt_tag = + (htt_tx_pdev_stats_sifs_tlv_v *)tag_buf; + uint8_t i; + uint8_t index = 0; + char sifs_status[DP_MAX_STRING_LEN]; + uint32_t tag_len = (HTT_STATS_TLV_LENGTH_GET(*tag_buf) >> 2); + + tag_len = qdf_min(tag_len, (uint32_t)HTT_TX_PDEV_MAX_SIFS_BURST_STATS); + DP_TRACE_STATS(NONE, "Pdev SIFS Stats:\n"); + for (i = 0; i < tag_len; i++) { + index += qdf_snprint(&sifs_status[index], + DP_MAX_STRING_LEN - index, " %d,", + dp_htt_tag->sifs_status[i]); + } + DP_TRACE_STATS(NONE, "sifs_status = %s ", sifs_status); +} + +/** + * dp_htt_stats_print_tag: function to select the tag type and + * print the corresponding tag structure + * @tag_type: tag type that is to be printed + * @tag_buf: pointer to the tag structure + * + * return: void + */ +void dp_htt_stats_print_tag(uint8_t tag_type, uint32_t *tag_buf) +{ + switch (tag_type) { + case HTT_STATS_TX_PDEV_CMN_TAG: + dp_print_tx_pdev_stats_cmn_tlv(tag_buf); + break; + case HTT_STATS_TX_PDEV_UNDERRUN_TAG: + dp_print_tx_pdev_stats_urrn_tlv_v(tag_buf); + break; + case HTT_STATS_TX_PDEV_SIFS_TAG: + dp_print_tx_pdev_stats_sifs_tlv_v(tag_buf); + break; + default: + break; + } +} diff --git a/dp/wifi3.0/dp_types.h b/dp/wifi3.0/dp_types.h index 8688bd4f32..27255c187b 100644 --- a/dp/wifi3.0/dp_types.h +++ b/dp/wifi3.0/dp_types.h @@ -633,6 +633,10 @@ struct dp_soc { u_int16_t pdev_bs_inact_interval; /* Inactivity timer */ #endif /* QCA_SUPPORT_SON */ + /* T2H Ext stats message queue */ + qdf_nbuf_queue_t htt_stats_msg; + /* T2H Ext stats message length */ + uint32_t htt_msg_len; }; #define MAX_RX_MAC_RINGS 2 /* Same as NAC_MAX_CLENT */ diff --git a/qdf/linux/src/i_qdf_util.h b/qdf/linux/src/i_qdf_util.h index e128974bf2..771db72307 100644 --- a/qdf/linux/src/i_qdf_util.h +++ b/qdf/linux/src/i_qdf_util.h @@ -220,8 +220,8 @@ static inline bool __qdf_is_macaddr_equal(struct qdf_mac_addr *mac_addr1, /** * @brief memory barriers. */ -#define __qdf_min(_a, _b) min(a, b) -#define __qdf_max(_a, _b) max(a, b) +#define __qdf_min(_a, _b) min(_a, _b) +#define __qdf_max(_a, _b) max(_a, _b) #define MEMINFO_KB(x) ((x) << (PAGE_SHIFT - 10)) /* In kilobytes */