diff --git a/utils/pktlog/include/pktlog_wifi2.h b/utils/pktlog/include/pktlog_wifi2.h new file mode 100644 index 0000000000..ec65957ed7 --- /dev/null +++ b/utils/pktlog/include/pktlog_wifi2.h @@ -0,0 +1,47 @@ +/** + * Copyright (c) 2013-2020, 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 "ol_txrx_types.h" +#include "ol_htt_tx_api.h" +#include "ol_tx_desc.h" +#include "qdf_mem.h" +#include "htt.h" +#include "htt_internal.h" +#include "pktlog_ac_i.h" +#include "wma_api.h" +#include "wlan_logging_sock_svc.h" + +#define TX_DESC_ID_LOW_MASK 0xffff +#define TX_DESC_ID_LOW_SHIFT 0 +#define TX_DESC_ID_HIGH_MASK 0xffff0000 +#define TX_DESC_ID_HIGH_SHIFT 16 + +#ifndef REMOVE_PKT_LOG +/** + * process_tx_info() - process tx pktlog buffers + * @txrx_pdev: ol pdev handle + * @data: pktlog buffer + * + * Return: 0 - success/non-zero - failure + */ +A_STATUS process_tx_info(struct cdp_pdev *txrx_pdev, void *data); +#else +static inline +A_STATUS process_tx_info(struct cdp_pdev *txrx_pdev, void *data) +{ + return 0; +} +#endif /* REMOVE_PKT_LOG */ diff --git a/utils/pktlog/pktlog_internal.c b/utils/pktlog/pktlog_internal.c index 7907bc3114..b0127fa523 100644 --- a/utils/pktlog/pktlog_internal.c +++ b/utils/pktlog/pktlog_internal.c @@ -42,11 +42,6 @@ #include "wma_api.h" #include "wlan_logging_sock_svc.h" -#define TX_DESC_ID_LOW_MASK 0xffff -#define TX_DESC_ID_LOW_SHIFT 0 -#define TX_DESC_ID_HIGH_MASK 0xffff0000 -#define TX_DESC_ID_HIGH_SHIFT 16 - #ifdef PKTLOG_HAS_SPECIFIC_DATA static inline void pktlog_hdr_set_specific_data(struct ath_pktlog_hdr *log_hdr, @@ -227,473 +222,6 @@ char *pktlog_getbuf(struct pktlog_dev_t *pl_dev, return plarg.buf; } -static struct txctl_frm_hdr frm_hdr; - -#ifndef HELIUMPLUS -static void process_ieee_hdr(void *data) -{ - uint8_t dir; - struct ieee80211_frame *wh = (struct ieee80211_frame *)(data); - - frm_hdr.framectrl = *(uint16_t *) (wh->i_fc); - frm_hdr.seqctrl = *(uint16_t *) (wh->i_seq); - dir = (wh->i_fc[1] & IEEE80211_FC1_DIR_MASK); - - if (dir == IEEE80211_FC1_DIR_TODS) { - frm_hdr.bssid_tail = - (wh->i_addr1[QDF_MAC_ADDR_SIZE - 2] << 8) | (wh-> - i_addr1 - [QDF_MAC_ADDR_SIZE - - 1]); - frm_hdr.sa_tail = - (wh->i_addr2[QDF_MAC_ADDR_SIZE - 2] << 8) | (wh-> - i_addr2 - [QDF_MAC_ADDR_SIZE - - 1]); - frm_hdr.da_tail = - (wh->i_addr3[QDF_MAC_ADDR_SIZE - 2] << 8) | (wh-> - i_addr3 - [QDF_MAC_ADDR_SIZE - - 1]); - } else if (dir == IEEE80211_FC1_DIR_FROMDS) { - frm_hdr.bssid_tail = - (wh->i_addr2[QDF_MAC_ADDR_SIZE - 2] << 8) | (wh-> - i_addr2 - [QDF_MAC_ADDR_SIZE - - 1]); - frm_hdr.sa_tail = - (wh->i_addr3[QDF_MAC_ADDR_SIZE - 2] << 8) | (wh-> - i_addr3 - [QDF_MAC_ADDR_SIZE - - 1]); - frm_hdr.da_tail = - (wh->i_addr1[QDF_MAC_ADDR_SIZE - 2] << 8) | (wh-> - i_addr1 - [QDF_MAC_ADDR_SIZE - - 1]); - } else { - frm_hdr.bssid_tail = - (wh->i_addr3[QDF_MAC_ADDR_SIZE - 2] << 8) | (wh-> - i_addr3 - [QDF_MAC_ADDR_SIZE - - 1]); - frm_hdr.sa_tail = - (wh->i_addr2[QDF_MAC_ADDR_SIZE - 2] << 8) | (wh-> - i_addr2 - [QDF_MAC_ADDR_SIZE - - 1]); - frm_hdr.da_tail = - (wh->i_addr1[QDF_MAC_ADDR_SIZE - 2] << 8) | (wh-> - i_addr1 - [QDF_MAC_ADDR_SIZE - - 1]); - } -} - -/** - * fill_ieee80211_hdr_data() - fill ieee802.11 data header - * @txrx_pdev: txrx pdev - * @pl_msdu_info: msdu info - * @data: data received from event - * - * Return: none - */ -/* TODO: Platform specific function */ -static void -fill_ieee80211_hdr_data(struct cdp_pdev *pdev, - struct ath_pktlog_msdu_info *pl_msdu_info, void *data) -{ - uint32_t i; - uint32_t *htt_tx_desc; - struct ol_tx_desc_t *tx_desc; - uint8_t msdu_id_offset = MSDU_ID_INFO_ID_OFFSET; - uint16_t tx_desc_id; - uint32_t *msdu_id_info = (uint32_t *) - ((void *)data + sizeof(struct ath_pktlog_hdr)); - uint32_t *msdu_id = (uint32_t *) ((char *)msdu_id_info + - msdu_id_offset); - uint8_t *addr, *vap_addr; - uint8_t vdev_id; - qdf_nbuf_t netbuf; - uint32_t len; - struct ol_txrx_pdev_t *txrx_pdev = (struct ol_txrx_pdev_t *)pdev; - - - pl_msdu_info->num_msdu = *msdu_id_info; - pl_msdu_info->priv_size = sizeof(uint32_t) * - pl_msdu_info->num_msdu + sizeof(uint32_t); - - if (pl_msdu_info->num_msdu > MAX_PKT_INFO_MSDU_ID) { - QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_ERROR, - "%s: Invalid num_msdu count", - __func__); - qdf_assert(0); - return; - } - for (i = 0; i < pl_msdu_info->num_msdu; i++) { - /* - * Handle big endianness - * Increment msdu_id once after retrieving - * lower 16 bits and uppper 16 bits - */ - if (!(i % 2)) { - tx_desc_id = ((*msdu_id & TX_DESC_ID_LOW_MASK) - >> TX_DESC_ID_LOW_SHIFT); - } else { - tx_desc_id = ((*msdu_id & TX_DESC_ID_HIGH_MASK) - >> TX_DESC_ID_HIGH_SHIFT); - msdu_id += 1; - } - if (tx_desc_id >= txrx_pdev->tx_desc.pool_size) { - QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_DEBUG, - "%s: drop due to invalid msdu id = %x", - __func__, tx_desc_id); - return; - } - tx_desc = ol_tx_desc_find(txrx_pdev, tx_desc_id); - qdf_assert(tx_desc); - netbuf = tx_desc->netbuf; - htt_tx_desc = (uint32_t *) tx_desc->htt_tx_desc; - qdf_assert(htt_tx_desc); - - qdf_nbuf_peek_header(netbuf, &addr, &len); - - if (len < (2 * QDF_MAC_ADDR_SIZE)) { - qdf_print("TX frame does not have a valid address"); - return; - } - /* Adding header information for the TX data frames */ - vdev_id = (uint8_t) (*(htt_tx_desc + - HTT_TX_VDEV_ID_WORD) >> - HTT_TX_VDEV_ID_SHIFT) & - HTT_TX_VDEV_ID_MASK; - - vap_addr = wma_get_vdev_address_by_vdev_id(vdev_id); - - frm_hdr.da_tail = (addr[QDF_MAC_ADDR_SIZE - 2] << 8) | - (addr[QDF_MAC_ADDR_SIZE - 1]); - frm_hdr.sa_tail = - (addr[2 * QDF_MAC_ADDR_SIZE - 2] << 8) | - (addr[2 * QDF_MAC_ADDR_SIZE - 1]); - if (vap_addr) { - frm_hdr.bssid_tail = - (vap_addr[QDF_MAC_ADDR_SIZE - 2] << 8) | - (vap_addr[QDF_MAC_ADDR_SIZE - 1]); - } else { - frm_hdr.bssid_tail = 0x0000; - } - pl_msdu_info->priv.msdu_len[i] = *(htt_tx_desc + - HTT_TX_MSDU_LEN_DWORD) - & HTT_TX_MSDU_LEN_MASK; - /* - * Add more information per MSDU - * e.g., protocol information - */ - } - -} -#endif - -#ifdef HELIUMPLUS -A_STATUS process_tx_info(struct cdp_pdev *txrx_pdev, void *data) -{ - /* - * Must include to process different types - * TX_CTL, TX_STATUS, TX_MSDU_ID, TX_FRM_HDR - */ - struct pktlog_dev_t *pl_dev = get_pktlog_handle(); - struct ath_pktlog_hdr pl_hdr; - struct ath_pktlog_info *pl_info; - uint32_t *pl_tgt_hdr; - struct ol_fw_data *fw_data; - uint32_t len; - - if (!txrx_pdev) { - qdf_nofl_info("Invalid pdev in %s", __func__); - return A_ERROR; - } - - if (!pl_dev) { - qdf_nofl_err("Invalid pktlog handle in %s", __func__); - qdf_assert(pl_dev); - return A_ERROR; - } - - qdf_assert(data); - - fw_data = (struct ol_fw_data *)data; - len = fw_data->len; - if (len < (sizeof(uint32_t) * - (ATH_PKTLOG_HDR_FLAGS_OFFSET + 1)) || - len < (sizeof(uint32_t) * - (ATH_PKTLOG_HDR_MISSED_CNT_OFFSET + 1)) || - len < (sizeof(uint32_t) * - (ATH_PKTLOG_HDR_LOG_TYPE_OFFSET + 1)) || - len < (sizeof(uint32_t) * - (ATH_PKTLOG_HDR_MAC_ID_OFFSET + 1)) || - len < (sizeof(uint32_t) * - (ATH_PKTLOG_HDR_SIZE_OFFSET + 1)) || - len < (sizeof(uint32_t) * - (ATH_PKTLOG_HDR_TYPE_SPECIFIC_DATA_OFFSET + 1))) { - qdf_print("Invalid msdu len in %s", __func__); - qdf_assert(0); - return A_ERROR; - } - - pl_tgt_hdr = (uint32_t *)fw_data->data; - /* - * Makes the short words (16 bits) portable b/w little endian - * and big endian - */ - pl_hdr.flags = (*(pl_tgt_hdr + ATH_PKTLOG_HDR_FLAGS_OFFSET) & - ATH_PKTLOG_HDR_FLAGS_MASK) >> - ATH_PKTLOG_HDR_FLAGS_SHIFT; - pl_hdr.flags |= PKTLOG_HDR_SIZE_16; - pl_hdr.missed_cnt = (*(pl_tgt_hdr + ATH_PKTLOG_HDR_MISSED_CNT_OFFSET) & - ATH_PKTLOG_HDR_MISSED_CNT_MASK) >> - ATH_PKTLOG_HDR_MISSED_CNT_SHIFT; - pl_hdr.log_type = (*(pl_tgt_hdr + ATH_PKTLOG_HDR_LOG_TYPE_OFFSET) & - ATH_PKTLOG_HDR_LOG_TYPE_MASK) >> - ATH_PKTLOG_HDR_LOG_TYPE_SHIFT; - pl_hdr.macId = (*(pl_tgt_hdr + ATH_PKTLOG_HDR_MAC_ID_OFFSET) & - ATH_PKTLOG_HDR_MAC_ID_MASK) >> - ATH_PKTLOG_HDR_MAC_ID_SHIFT; - pl_hdr.size = (*(pl_tgt_hdr + ATH_PKTLOG_HDR_SIZE_OFFSET) & - ATH_PKTLOG_HDR_SIZE_MASK) >> ATH_PKTLOG_HDR_SIZE_SHIFT; - pl_hdr.timestamp = *(pl_tgt_hdr + ATH_PKTLOG_HDR_TIMESTAMP_OFFSET); - pl_hdr.type_specific_data = - *(pl_tgt_hdr + ATH_PKTLOG_HDR_TYPE_SPECIFIC_DATA_OFFSET); - pl_info = pl_dev->pl_info; - - if (sizeof(struct ath_pktlog_hdr) + pl_hdr.size > len) { - qdf_assert(0); - return A_ERROR; - } - - if (pl_hdr.log_type == PKTLOG_TYPE_TX_CTRL) { - size_t log_size = sizeof(frm_hdr) + pl_hdr.size; - void *txdesc_hdr_ctl = (void *) - pktlog_getbuf(pl_dev, pl_info, log_size, &pl_hdr); - qdf_assert(txdesc_hdr_ctl); - qdf_assert(pl_hdr.size < (370 * sizeof(u_int32_t))); - - qdf_mem_copy(txdesc_hdr_ctl, &frm_hdr, sizeof(frm_hdr)); - qdf_mem_copy((char *)txdesc_hdr_ctl + sizeof(frm_hdr), - ((void *)fw_data->data + - sizeof(struct ath_pktlog_hdr)), - pl_hdr.size); - pl_hdr.size = log_size; - cds_pkt_stats_to_logger_thread(&pl_hdr, NULL, - txdesc_hdr_ctl); - } - - if (pl_hdr.log_type == PKTLOG_TYPE_TX_STAT) { - struct ath_pktlog_tx_status txstat_log; - size_t log_size = pl_hdr.size; - - txstat_log.ds_status = (void *) - pktlog_getbuf(pl_dev, pl_info, - log_size, &pl_hdr); - qdf_assert(txstat_log.ds_status); - qdf_mem_copy(txstat_log.ds_status, - ((void *)fw_data->data + - sizeof(struct ath_pktlog_hdr)), - pl_hdr.size); - /* TODO: MCL specific API */ - cds_pkt_stats_to_logger_thread(&pl_hdr, NULL, - txstat_log.ds_status); - } - return A_OK; -} -#else -A_STATUS process_tx_info(struct cdp_pdev *txrx_pdev, void *data) -{ - /* - * Must include to process different types - * TX_CTL, TX_STATUS, TX_MSDU_ID, TX_FRM_HDR - */ - struct pktlog_dev_t *pl_dev = get_pktlog_handle(); - struct ath_pktlog_hdr pl_hdr; - struct ath_pktlog_info *pl_info; - uint32_t *pl_tgt_hdr; - struct ol_fw_data *fw_data; - uint32_t len; - - if (!txrx_pdev) { - qdf_print("Invalid pdev in %s", __func__); - return A_ERROR; - } - - if (!pl_dev) { - qdf_nofl_err("Invalid pktlog handle in %s", __func__); - qdf_assert(pl_dev); - return A_ERROR; - } - - qdf_assert(data); - - fw_data = (struct ol_fw_data *)data; - len = fw_data->len; - if (len < (sizeof(uint32_t) * - (ATH_PKTLOG_HDR_FLAGS_OFFSET + 1)) || - len < (sizeof(uint32_t) * - (ATH_PKTLOG_HDR_MISSED_CNT_OFFSET + 1)) || - len < (sizeof(uint32_t) * - (ATH_PKTLOG_HDR_LOG_TYPE_OFFSET + 1)) || - len < (sizeof(uint32_t) * - (ATH_PKTLOG_HDR_SIZE_OFFSET + 1)) || - len < (sizeof(uint32_t) * - (ATH_PKTLOG_HDR_TYPE_SPECIFIC_DATA_OFFSET + 1))) { - qdf_print("Invalid msdu len in %s", __func__); - qdf_assert(0); - return A_ERROR; - } - - pl_tgt_hdr = (uint32_t *)fw_data->data; - /* - * Makes the short words (16 bits) portable b/w little endian - * and big endian - */ - pl_hdr.flags = (*(pl_tgt_hdr + ATH_PKTLOG_HDR_FLAGS_OFFSET) & - ATH_PKTLOG_HDR_FLAGS_MASK) >> - ATH_PKTLOG_HDR_FLAGS_SHIFT; - pl_hdr.missed_cnt = (*(pl_tgt_hdr + ATH_PKTLOG_HDR_MISSED_CNT_OFFSET) & - ATH_PKTLOG_HDR_MISSED_CNT_MASK) >> - ATH_PKTLOG_HDR_MISSED_CNT_SHIFT; - pl_hdr.log_type = (*(pl_tgt_hdr + ATH_PKTLOG_HDR_LOG_TYPE_OFFSET) & - ATH_PKTLOG_HDR_LOG_TYPE_MASK) >> - ATH_PKTLOG_HDR_LOG_TYPE_SHIFT; - pl_hdr.size = (*(pl_tgt_hdr + ATH_PKTLOG_HDR_SIZE_OFFSET) & - ATH_PKTLOG_HDR_SIZE_MASK) >> ATH_PKTLOG_HDR_SIZE_SHIFT; - pl_hdr.timestamp = *(pl_tgt_hdr + ATH_PKTLOG_HDR_TIMESTAMP_OFFSET); - - pktlog_hdr_set_specific_data(&pl_hdr, - *(pl_tgt_hdr + - ATH_PKTLOG_HDR_TYPE_SPECIFIC_DATA_OFFSET)); - - pl_info = pl_dev->pl_info; - - if (pl_hdr.log_type == PKTLOG_TYPE_TX_FRM_HDR) { - /* Valid only for the TX CTL */ - process_ieee_hdr(fw_data->data + sizeof(pl_hdr)); - } - - if (pl_hdr.log_type == PKTLOG_TYPE_TX_VIRT_ADDR) { - uint32_t desc_id = (uint32_t) *((uint32_t *)(fw_data->data + - sizeof(pl_hdr))); - uint32_t vdev_id = desc_id; - - /* if the pkt log msg is for the bcn frame the vdev id - * is piggybacked in desc_id and the MSB of the desc ID - * would be set to FF - */ -#define BCN_DESC_ID 0xFF - if ((desc_id >> 24) == BCN_DESC_ID) { - void *data; - uint32_t buf_size; - - vdev_id &= 0x00FFFFFF; - /* TODO: MCL specific API */ - data = wma_get_beacon_buffer_by_vdev_id(vdev_id, - &buf_size); - if (data) { - /* TODO: platform specific API */ - process_ieee_hdr(data); - qdf_mem_free(data); - } - } else { - /* - * TODO: get the hdr content for mgmt frames from - * Tx mgmt desc pool - */ - } - } - - if (pl_hdr.log_type == PKTLOG_TYPE_TX_CTRL) { - struct ath_pktlog_txctl txctl_log; - size_t log_size = sizeof(txctl_log.priv); - - txctl_log.txdesc_hdr_ctl = (void *)pktlog_getbuf(pl_dev, - pl_info, - log_size, - &pl_hdr); - - if (!txctl_log.txdesc_hdr_ctl) { - qdf_nofl_info - ("failed to get txctl_log.txdesc_hdr_ctl buf"); - return A_ERROR; - } - - /* - * frm hdr is currently Valid only for local frames - * Add capability to include the fmr hdr for remote frames - */ - txctl_log.priv.frm_hdr = frm_hdr; - qdf_assert(txctl_log.priv.txdesc_ctl); - qdf_assert(pl_hdr.size < sizeof(txctl_log.priv.txdesc_ctl)); - pl_hdr.size = (pl_hdr.size > sizeof(txctl_log.priv.txdesc_ctl)) - ? sizeof(txctl_log.priv.txdesc_ctl) : - pl_hdr.size; - - if (sizeof(struct ath_pktlog_hdr) + pl_hdr.size > len) { - qdf_assert(0); - return A_ERROR; - } - qdf_mem_copy((void *)&txctl_log.priv.txdesc_ctl, - ((void *)fw_data->data + - sizeof(struct ath_pktlog_hdr)), - pl_hdr.size); - qdf_assert(txctl_log.txdesc_hdr_ctl); - qdf_mem_copy(txctl_log.txdesc_hdr_ctl, &txctl_log.priv, - sizeof(txctl_log.priv)); - pl_hdr.size = log_size; - cds_pkt_stats_to_logger_thread(&pl_hdr, NULL, - txctl_log.txdesc_hdr_ctl); - /* Add Protocol information and HT specific information */ - } - - if (pl_hdr.log_type == PKTLOG_TYPE_TX_STAT) { - struct ath_pktlog_tx_status txstat_log; - size_t log_size = pl_hdr.size; - - txstat_log.ds_status = (void *) - pktlog_getbuf(pl_dev, pl_info, log_size, &pl_hdr); - qdf_assert(txstat_log.ds_status); - qdf_mem_copy(txstat_log.ds_status, - ((void *)fw_data->data + - sizeof(struct ath_pktlog_hdr)), - pl_hdr.size); - - cds_pkt_stats_to_logger_thread(&pl_hdr, NULL, - txstat_log.ds_status); - } - - if (pl_hdr.log_type == PKTLOG_TYPE_TX_MSDU_ID) { - struct ath_pktlog_msdu_info pl_msdu_info; - size_t log_size; - - qdf_mem_zero(&pl_msdu_info, sizeof(pl_msdu_info)); - log_size = sizeof(pl_msdu_info.priv); - - if (pl_dev->mt_pktlog_enabled == false) - fill_ieee80211_hdr_data(txrx_pdev, - &pl_msdu_info, fw_data->data); - - pl_msdu_info.ath_msdu_info = pktlog_getbuf(pl_dev, pl_info, - log_size, &pl_hdr); - qdf_mem_copy((void *)&pl_msdu_info.priv.msdu_id_info, - ((void *)fw_data->data + - sizeof(struct ath_pktlog_hdr)), - sizeof(pl_msdu_info.priv.msdu_id_info)); - qdf_mem_copy(pl_msdu_info.ath_msdu_info, &pl_msdu_info.priv, - sizeof(pl_msdu_info.priv)); - cds_pkt_stats_to_logger_thread(&pl_hdr, NULL, - pl_msdu_info.ath_msdu_info); - } - - return A_OK; -} -#endif /* TODO: hardware dependent function */ diff --git a/utils/pktlog/pktlog_wifi2.c b/utils/pktlog/pktlog_wifi2.c new file mode 100644 index 0000000000..3ec45d14f3 --- /dev/null +++ b/utils/pktlog/pktlog_wifi2.c @@ -0,0 +1,494 @@ +/** + * Copyright (c) 2013-2020, 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. + */ + +/* WIFI2 - Refers to legacy platforms */ +#include "pktlog_wifi2.h" + +static struct txctl_frm_hdr frm_hdr; + +#ifndef HELIUMPLUS +/** + * process_ieee_hdr(): Process ieee header from the pktlog buffer + * @data: pktlog buffer + * + * Return: None + */ +static void process_ieee_hdr(void *data) +{ + uint8_t dir; + struct ieee80211_frame *wh = (struct ieee80211_frame *)(data); + + frm_hdr.framectrl = *(uint16_t *)(wh->i_fc); + frm_hdr.seqctrl = *(uint16_t *)(wh->i_seq); + dir = (wh->i_fc[1] & IEEE80211_FC1_DIR_MASK); + + if (dir == IEEE80211_FC1_DIR_TODS) { + frm_hdr.bssid_tail = + (wh->i_addr1[QDF_MAC_ADDR_SIZE - 2] << 8) | (wh-> + i_addr1 + [QDF_MAC_ADDR_SIZE + - 1]); + frm_hdr.sa_tail = + (wh->i_addr2[QDF_MAC_ADDR_SIZE - 2] << 8) | (wh-> + i_addr2 + [QDF_MAC_ADDR_SIZE + - 1]); + frm_hdr.da_tail = + (wh->i_addr3[QDF_MAC_ADDR_SIZE - 2] << 8) | (wh-> + i_addr3 + [QDF_MAC_ADDR_SIZE + - 1]); + } else if (dir == IEEE80211_FC1_DIR_FROMDS) { + frm_hdr.bssid_tail = + (wh->i_addr2[QDF_MAC_ADDR_SIZE - 2] << 8) | (wh-> + i_addr2 + [QDF_MAC_ADDR_SIZE + - 1]); + frm_hdr.sa_tail = + (wh->i_addr3[QDF_MAC_ADDR_SIZE - 2] << 8) | (wh-> + i_addr3 + [QDF_MAC_ADDR_SIZE + - 1]); + frm_hdr.da_tail = + (wh->i_addr1[QDF_MAC_ADDR_SIZE - 2] << 8) | (wh-> + i_addr1 + [QDF_MAC_ADDR_SIZE + - 1]); + } else { + frm_hdr.bssid_tail = + (wh->i_addr3[QDF_MAC_ADDR_SIZE - 2] << 8) | (wh-> + i_addr3 + [QDF_MAC_ADDR_SIZE + - 1]); + frm_hdr.sa_tail = + (wh->i_addr2[QDF_MAC_ADDR_SIZE - 2] << 8) | (wh-> + i_addr2 + [QDF_MAC_ADDR_SIZE + - 1]); + frm_hdr.da_tail = + (wh->i_addr1[QDF_MAC_ADDR_SIZE - 2] << 8) | (wh-> + i_addr1 + [QDF_MAC_ADDR_SIZE + - 1]); + } +} + +/** + * fill_ieee80211_hdr_data() - fill ieee802.11 data header + * @txrx_pdev: txrx pdev + * @pl_msdu_info: msdu info + * @data: data received from event + * + * Return: none + */ +/* TODO: Platform specific function */ +static void +fill_ieee80211_hdr_data(struct cdp_pdev *pdev, + struct ath_pktlog_msdu_info *pl_msdu_info, + void *data) +{ + uint32_t i; + uint32_t *htt_tx_desc; + struct ol_tx_desc_t *tx_desc; + uint8_t msdu_id_offset = MSDU_ID_INFO_ID_OFFSET; + uint16_t tx_desc_id; + uint32_t *msdu_id_info = (uint32_t *) + ((void *)data + sizeof(struct ath_pktlog_hdr)); + uint32_t *msdu_id = (uint32_t *)((char *)msdu_id_info + + msdu_id_offset); + uint8_t *addr, *vap_addr; + uint8_t vdev_id; + qdf_nbuf_t netbuf; + uint32_t len; + struct ol_txrx_pdev_t *txrx_pdev = (struct ol_txrx_pdev_t *)pdev; + + pl_msdu_info->num_msdu = *msdu_id_info; + pl_msdu_info->priv_size = sizeof(uint32_t) * + pl_msdu_info->num_msdu + sizeof(uint32_t); + + if (pl_msdu_info->num_msdu > MAX_PKT_INFO_MSDU_ID) { + QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_ERROR, + "%s: Invalid num_msdu count", + __func__); + qdf_assert(0); + return; + } + for (i = 0; i < pl_msdu_info->num_msdu; i++) { + /* + * Handle big endianness + * Increment msdu_id once after retrieving + * lower 16 bits and uppper 16 bits + */ + if (!(i % 2)) { + tx_desc_id = ((*msdu_id & TX_DESC_ID_LOW_MASK) + >> TX_DESC_ID_LOW_SHIFT); + } else { + tx_desc_id = ((*msdu_id & TX_DESC_ID_HIGH_MASK) + >> TX_DESC_ID_HIGH_SHIFT); + msdu_id += 1; + } + if (tx_desc_id >= txrx_pdev->tx_desc.pool_size) { + QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_DEBUG, + "%s: drop due to invalid msdu id = %x", + __func__, tx_desc_id); + return; + } + tx_desc = ol_tx_desc_find(txrx_pdev, tx_desc_id); + qdf_assert(tx_desc); + netbuf = tx_desc->netbuf; + htt_tx_desc = (uint32_t *)tx_desc->htt_tx_desc; + qdf_assert(htt_tx_desc); + + qdf_nbuf_peek_header(netbuf, &addr, &len); + + if (len < (2 * QDF_MAC_ADDR_SIZE)) { + qdf_print("TX frame does not have a valid address"); + return; + } + /* Adding header information for the TX data frames */ + vdev_id = (uint8_t)(*(htt_tx_desc + + HTT_TX_VDEV_ID_WORD) >> + HTT_TX_VDEV_ID_SHIFT) & + HTT_TX_VDEV_ID_MASK; + + vap_addr = wma_get_vdev_address_by_vdev_id(vdev_id); + + frm_hdr.da_tail = (addr[QDF_MAC_ADDR_SIZE - 2] << 8) | + (addr[QDF_MAC_ADDR_SIZE - 1]); + frm_hdr.sa_tail = + (addr[2 * QDF_MAC_ADDR_SIZE - 2] << 8) | + (addr[2 * QDF_MAC_ADDR_SIZE - 1]); + if (vap_addr) { + frm_hdr.bssid_tail = + (vap_addr[QDF_MAC_ADDR_SIZE - 2] << 8) | + (vap_addr[QDF_MAC_ADDR_SIZE - 1]); + } else { + frm_hdr.bssid_tail = 0x0000; + } + pl_msdu_info->priv.msdu_len[i] = *(htt_tx_desc + + HTT_TX_MSDU_LEN_DWORD) + & HTT_TX_MSDU_LEN_MASK; + /* + * Add more information per MSDU + * e.g., protocol information + */ + } +} +#endif /* HELIUMPLUS */ + +#ifdef HELIUMPLUS +A_STATUS process_tx_info(struct cdp_pdev *txrx_pdev, void *data) +{ + /* + * Must include to process different types + * TX_CTL, TX_STATUS, TX_MSDU_ID, TX_FRM_HDR + */ + struct pktlog_dev_t *pl_dev = get_pktlog_handle(); + struct ath_pktlog_hdr pl_hdr; + struct ath_pktlog_info *pl_info; + uint32_t *pl_tgt_hdr; + struct ol_fw_data *fw_data; + uint32_t len; + + if (!txrx_pdev) { + qdf_nofl_info("Invalid pdev in %s", __func__); + return A_ERROR; + } + + if (!pl_dev) { + qdf_nofl_err("Invalid pktlog handle in %s", __func__); + qdf_assert(pl_dev); + return A_ERROR; + } + + qdf_assert(data); + + fw_data = (struct ol_fw_data *)data; + len = fw_data->len; + if (len < (sizeof(uint32_t) * + (ATH_PKTLOG_HDR_FLAGS_OFFSET + 1)) || + len < (sizeof(uint32_t) * + (ATH_PKTLOG_HDR_MISSED_CNT_OFFSET + 1)) || + len < (sizeof(uint32_t) * + (ATH_PKTLOG_HDR_LOG_TYPE_OFFSET + 1)) || + len < (sizeof(uint32_t) * + (ATH_PKTLOG_HDR_MAC_ID_OFFSET + 1)) || + len < (sizeof(uint32_t) * + (ATH_PKTLOG_HDR_SIZE_OFFSET + 1)) || + len < (sizeof(uint32_t) * + (ATH_PKTLOG_HDR_TYPE_SPECIFIC_DATA_OFFSET + 1))) { + qdf_print("Invalid msdu len in %s", __func__); + qdf_assert(0); + return A_ERROR; + } + + pl_tgt_hdr = (uint32_t *)fw_data->data; + /* + * Makes the short words (16 bits) portable b/w little endian + * and big endian + */ + pl_hdr.flags = (*(pl_tgt_hdr + ATH_PKTLOG_HDR_FLAGS_OFFSET) & + ATH_PKTLOG_HDR_FLAGS_MASK) >> + ATH_PKTLOG_HDR_FLAGS_SHIFT; + pl_hdr.flags |= PKTLOG_HDR_SIZE_16; + pl_hdr.missed_cnt = (*(pl_tgt_hdr + ATH_PKTLOG_HDR_MISSED_CNT_OFFSET) & + ATH_PKTLOG_HDR_MISSED_CNT_MASK) >> + ATH_PKTLOG_HDR_MISSED_CNT_SHIFT; + pl_hdr.log_type = (*(pl_tgt_hdr + ATH_PKTLOG_HDR_LOG_TYPE_OFFSET) & + ATH_PKTLOG_HDR_LOG_TYPE_MASK) >> + ATH_PKTLOG_HDR_LOG_TYPE_SHIFT; + pl_hdr.macId = (*(pl_tgt_hdr + ATH_PKTLOG_HDR_MAC_ID_OFFSET) & + ATH_PKTLOG_HDR_MAC_ID_MASK) >> + ATH_PKTLOG_HDR_MAC_ID_SHIFT; + pl_hdr.size = (*(pl_tgt_hdr + ATH_PKTLOG_HDR_SIZE_OFFSET) & + ATH_PKTLOG_HDR_SIZE_MASK) >> ATH_PKTLOG_HDR_SIZE_SHIFT; + pl_hdr.timestamp = *(pl_tgt_hdr + ATH_PKTLOG_HDR_TIMESTAMP_OFFSET); + pl_hdr.type_specific_data = + *(pl_tgt_hdr + ATH_PKTLOG_HDR_TYPE_SPECIFIC_DATA_OFFSET); + pl_info = pl_dev->pl_info; + + if (sizeof(struct ath_pktlog_hdr) + pl_hdr.size > len) { + qdf_assert(0); + return A_ERROR; + } + + if (pl_hdr.log_type == PKTLOG_TYPE_TX_CTRL) { + size_t log_size = sizeof(frm_hdr) + pl_hdr.size; + void *txdesc_hdr_ctl = (void *) + pktlog_getbuf(pl_dev, pl_info, + log_size, &pl_hdr); + + qdf_assert(txdesc_hdr_ctl); + qdf_assert(pl_hdr.size < (370 * sizeof(u_int32_t))); + + qdf_mem_copy(txdesc_hdr_ctl, &frm_hdr, sizeof(frm_hdr)); + qdf_mem_copy((char *)txdesc_hdr_ctl + sizeof(frm_hdr), + ((void *)fw_data->data + + sizeof(struct ath_pktlog_hdr)), + pl_hdr.size); + pl_hdr.size = log_size; + cds_pkt_stats_to_logger_thread(&pl_hdr, NULL, + txdesc_hdr_ctl); + } + + if (pl_hdr.log_type == PKTLOG_TYPE_TX_STAT) { + struct ath_pktlog_tx_status txstat_log; + size_t log_size = pl_hdr.size; + + txstat_log.ds_status = (void *) + pktlog_getbuf(pl_dev, pl_info, + log_size, &pl_hdr); + qdf_assert(txstat_log.ds_status); + qdf_mem_copy(txstat_log.ds_status, + ((void *)fw_data->data + + sizeof(struct ath_pktlog_hdr)), + pl_hdr.size); + /* TODO: MCL specific API */ + cds_pkt_stats_to_logger_thread(&pl_hdr, NULL, + txstat_log.ds_status); + } + return A_OK; +} +#else +A_STATUS process_tx_info(struct cdp_pdev *txrx_pdev, void *data) +{ + /* + * Must include to process different types + * TX_CTL, TX_STATUS, TX_MSDU_ID, TX_FRM_HDR + */ + struct pktlog_dev_t *pl_dev = get_pktlog_handle(); + struct ath_pktlog_hdr pl_hdr; + struct ath_pktlog_info *pl_info; + uint32_t *pl_tgt_hdr; + struct ol_fw_data *fw_data; + uint32_t len; + + if (!txrx_pdev) { + qdf_print("Invalid pdev in %s", __func__); + return A_ERROR; + } + + if (!pl_dev) { + qdf_nofl_err("Invalid pktlog handle in %s", __func__); + qdf_assert(pl_dev); + return A_ERROR; + } + + qdf_assert(data); + + fw_data = (struct ol_fw_data *)data; + len = fw_data->len; + if (len < (sizeof(uint32_t) * + (ATH_PKTLOG_HDR_FLAGS_OFFSET + 1)) || + len < (sizeof(uint32_t) * + (ATH_PKTLOG_HDR_MISSED_CNT_OFFSET + 1)) || + len < (sizeof(uint32_t) * + (ATH_PKTLOG_HDR_LOG_TYPE_OFFSET + 1)) || + len < (sizeof(uint32_t) * + (ATH_PKTLOG_HDR_SIZE_OFFSET + 1)) || + len < (sizeof(uint32_t) * + (ATH_PKTLOG_HDR_TYPE_SPECIFIC_DATA_OFFSET + 1))) { + qdf_print("Invalid msdu len in %s", __func__); + qdf_assert(0); + return A_ERROR; + } + + pl_tgt_hdr = (uint32_t *)fw_data->data; + /* + * Makes the short words (16 bits) portable b/w little endian + * and big endian + */ + pl_hdr.flags = (*(pl_tgt_hdr + ATH_PKTLOG_HDR_FLAGS_OFFSET) & + ATH_PKTLOG_HDR_FLAGS_MASK) >> + ATH_PKTLOG_HDR_FLAGS_SHIFT; + pl_hdr.missed_cnt = (*(pl_tgt_hdr + ATH_PKTLOG_HDR_MISSED_CNT_OFFSET) & + ATH_PKTLOG_HDR_MISSED_CNT_MASK) >> + ATH_PKTLOG_HDR_MISSED_CNT_SHIFT; + pl_hdr.log_type = (*(pl_tgt_hdr + ATH_PKTLOG_HDR_LOG_TYPE_OFFSET) & + ATH_PKTLOG_HDR_LOG_TYPE_MASK) >> + ATH_PKTLOG_HDR_LOG_TYPE_SHIFT; + pl_hdr.size = (*(pl_tgt_hdr + ATH_PKTLOG_HDR_SIZE_OFFSET) & + ATH_PKTLOG_HDR_SIZE_MASK) >> ATH_PKTLOG_HDR_SIZE_SHIFT; + pl_hdr.timestamp = *(pl_tgt_hdr + ATH_PKTLOG_HDR_TIMESTAMP_OFFSET); + + pktlog_hdr_set_specific_data(&pl_hdr, + *(pl_tgt_hdr + + ATH_PKTLOG_HDR_TYPE_SPECIFIC_DATA_OFFSET)); + + pl_info = pl_dev->pl_info; + + if (pl_hdr.log_type == PKTLOG_TYPE_TX_FRM_HDR) { + /* Valid only for the TX CTL */ + process_ieee_hdr(fw_data->data + sizeof(pl_hdr)); + } + + if (pl_hdr.log_type == PKTLOG_TYPE_TX_VIRT_ADDR) { + uint32_t desc_id = (uint32_t)*((uint32_t *)(fw_data->data + + sizeof(pl_hdr))); + uint32_t vdev_id = desc_id; + + /* if the pkt log msg is for the bcn frame the vdev id + * is piggybacked in desc_id and the MSB of the desc ID + * would be set to FF + */ +#define BCN_DESC_ID 0xFF + if ((desc_id >> 24) == BCN_DESC_ID) { + void *data; + uint32_t buf_size; + + vdev_id &= 0x00FFFFFF; + /* TODO: MCL specific API */ + data = wma_get_beacon_buffer_by_vdev_id(vdev_id, + &buf_size); + if (data) { + /* TODO: platform specific API */ + process_ieee_hdr(data); + qdf_mem_free(data); + } + } else { + /* + * TODO: get the hdr content for mgmt frames from + * Tx mgmt desc pool + */ + } + } + + if (pl_hdr.log_type == PKTLOG_TYPE_TX_CTRL) { + struct ath_pktlog_txctl txctl_log; + size_t log_size = sizeof(txctl_log.priv); + + txctl_log.txdesc_hdr_ctl = (void *)pktlog_getbuf(pl_dev, + pl_info, + log_size, + &pl_hdr); + + if (!txctl_log.txdesc_hdr_ctl) { + qdf_nofl_info + ("failed to get txctl_log.txdesc_hdr_ctl buf"); + return A_ERROR; + } + + /* + * frm hdr is currently Valid only for local frames + * Add capability to include the fmr hdr for remote frames + */ + txctl_log.priv.frm_hdr = frm_hdr; + qdf_assert(txctl_log.priv.txdesc_ctl); + qdf_assert(pl_hdr.size < sizeof(txctl_log.priv.txdesc_ctl)); + pl_hdr.size = (pl_hdr.size > sizeof(txctl_log.priv.txdesc_ctl)) + ? sizeof(txctl_log.priv.txdesc_ctl) : + pl_hdr.size; + + if (sizeof(struct ath_pktlog_hdr) + pl_hdr.size > len) { + qdf_assert(0); + return A_ERROR; + } + qdf_mem_copy((void *)&txctl_log.priv.txdesc_ctl, + ((void *)fw_data->data + + sizeof(struct ath_pktlog_hdr)), + pl_hdr.size); + qdf_assert(txctl_log.txdesc_hdr_ctl); + qdf_mem_copy(txctl_log.txdesc_hdr_ctl, &txctl_log.priv, + sizeof(txctl_log.priv)); + pl_hdr.size = log_size; + cds_pkt_stats_to_logger_thread(&pl_hdr, NULL, + txctl_log.txdesc_hdr_ctl); + /* Add Protocol information and HT specific information */ + } + + if (pl_hdr.log_type == PKTLOG_TYPE_TX_STAT) { + struct ath_pktlog_tx_status txstat_log; + size_t log_size = pl_hdr.size; + + txstat_log.ds_status = (void *) + pktlog_getbuf(pl_dev, pl_info, + log_size, &pl_hdr); + qdf_assert(txstat_log.ds_status); + qdf_mem_copy(txstat_log.ds_status, + ((void *)fw_data->data + + sizeof(struct ath_pktlog_hdr)), + pl_hdr.size); + + cds_pkt_stats_to_logger_thread(&pl_hdr, NULL, + txstat_log.ds_status); + } + + if (pl_hdr.log_type == PKTLOG_TYPE_TX_MSDU_ID) { + struct ath_pktlog_msdu_info pl_msdu_info; + size_t log_size; + + qdf_mem_zero(&pl_msdu_info, sizeof(pl_msdu_info)); + log_size = sizeof(pl_msdu_info.priv); + + if (pl_dev->mt_pktlog_enabled == false) + fill_ieee80211_hdr_data(txrx_pdev, + &pl_msdu_info, fw_data->data); + + pl_msdu_info.ath_msdu_info = pktlog_getbuf(pl_dev, pl_info, + log_size, &pl_hdr); + qdf_mem_copy((void *)&pl_msdu_info.priv.msdu_id_info, + ((void *)fw_data->data + + sizeof(struct ath_pktlog_hdr)), + sizeof(pl_msdu_info.priv.msdu_id_info)); + qdf_mem_copy(pl_msdu_info.ath_msdu_info, &pl_msdu_info.priv, + sizeof(pl_msdu_info.priv)); + cds_pkt_stats_to_logger_thread(&pl_hdr, NULL, + pl_msdu_info.ath_msdu_info); + } + + return A_OK; +} +#endif /* HELIUMPLUS */ diff --git a/utils/pktlog/pktlog_wifi3.c b/utils/pktlog/pktlog_wifi3.c index 01c8f60d6c..c74c7374aa 100644 --- a/utils/pktlog/pktlog_wifi3.c +++ b/utils/pktlog/pktlog_wifi3.c @@ -27,7 +27,6 @@ process_offload_pktlog_wifi3(struct cdp_pdev *pdev, void *data) uint32_t *pl_tgt_hdr; void *txdesc_hdr_ctl = NULL; size_t log_size = 0; - size_t tmp_log_size = 0; if (!pl_dev) { QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_ERROR, @@ -56,9 +55,8 @@ process_offload_pktlog_wifi3(struct cdp_pdev *pdev, void *data) ATH_PKTLOG_HDR_SIZE_MASK) >> ATH_PKTLOG_HDR_SIZE_SHIFT; pl_hdr.timestamp = *(pl_tgt_hdr + ATH_PKTLOG_HDR_TIMESTAMP_OFFSET); - pktlog_hdr_set_specific_data(&pl_hdr, - *(pl_tgt_hdr + - ATH_PKTLOG_HDR_TYPE_SPECIFIC_DATA_OFFSET)); + pl_hdr.type_specific_data = *(pl_tgt_hdr + + ATH_PKTLOG_HDR_TYPE_SPECIFIC_DATA_OFFSET); if (pl_hdr.size > MAX_PKTLOG_RECV_BUF_SIZE) { pl_dev->invalid_packets++; @@ -70,7 +68,6 @@ process_offload_pktlog_wifi3(struct cdp_pdev *pdev, void *data) * TX_CTL, TX_STATUS, TX_MSDU_ID, TX_FRM_HDR */ pl_info = pl_dev->pl_info; - tmp_log_size = sizeof(frm_hdr) + pl_hdr.size; log_size = pl_hdr.size; txdesc_hdr_ctl = (void *)pktlog_getbuf(pl_dev, pl_info, log_size, &pl_hdr);