From a2deef8c83ea5e2b2c716cb5cc67e0964ccedf8c Mon Sep 17 00:00:00 2001 From: Vulupala Shashank Reddy Date: Wed, 29 Jan 2020 11:16:39 +0530 Subject: [PATCH] qcacld-3.0: Process Rx data packet for pkt capture mode Process Rx data packets and post to the mon thread for packet capture mode Change-Id: Id8ae54677615c27d61c6def1a521c509f602863b CRs-Fixed: 2618941 --- Kbuild | 1 + .../core/inc/wlan_pkt_capture_data_txrx.h | 101 +++++ .../core/inc/wlan_pkt_capture_main.h | 8 + .../core/inc/wlan_pkt_capture_mon_thread.h | 12 +- .../core/src/wlan_pkt_capture_data_txrx.c | 370 ++++++++++++++++++ .../core/src/wlan_pkt_capture_main.c | 9 + .../core/src/wlan_pkt_capture_mgmt_txrx.c | 6 +- .../core/src/wlan_pkt_capture_mon_thread.c | 4 +- .../inc/wlan_pkt_capture_ucfg_api.h | 53 +++ .../src/wlan_pkt_capture_ucfg_api.c | 20 + core/dp/htt/htt_internal.h | 22 +- core/dp/htt/htt_monitor_rx.c | 14 +- core/dp/txrx/ol_rx.c | 47 +++ core/dp/txrx/ol_rx_defrag.c | 37 +- 14 files changed, 683 insertions(+), 21 deletions(-) create mode 100644 components/pkt_capture/core/inc/wlan_pkt_capture_data_txrx.h create mode 100644 components/pkt_capture/core/src/wlan_pkt_capture_data_txrx.c diff --git a/Kbuild b/Kbuild index bc694bf03c..2ddbcd38f8 100644 --- a/Kbuild +++ b/Kbuild @@ -1053,6 +1053,7 @@ PKT_CAPTURE_OBJS := $(PKT_CAPTURE_DIR)/core/src/wlan_pkt_capture_main.o \ $(PKT_CAPTURE_DIR)/core/src/wlan_pkt_capture_mon_thread.o \ $(PKT_CAPTURE_DIR)/dispatcher/src/wlan_pkt_capture_ucfg_api.o \ $(PKT_CAPTURE_DIR)/core/src/wlan_pkt_capture_mgmt_txrx.o \ + $(PKT_CAPTURE_DIR)/core/src/wlan_pkt_capture_data_txrx.o \ $(PKT_CAPTURE_DIR)/dispatcher/src/wlan_pkt_capture_ucfg_api.o \ $(PKT_CAPTURE_TARGET_IF_DIR)/src/target_if_pkt_capture.o endif diff --git a/components/pkt_capture/core/inc/wlan_pkt_capture_data_txrx.h b/components/pkt_capture/core/inc/wlan_pkt_capture_data_txrx.h new file mode 100644 index 0000000000..ba60761515 --- /dev/null +++ b/components/pkt_capture/core/inc/wlan_pkt_capture_data_txrx.h @@ -0,0 +1,101 @@ +/* + * Copyright (c) 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. + */ + +/** + * DOC: Declare private API which shall be used internally only + * in pkt_capture component. This file shall include prototypes of + * pkt_capture data tx and data rx. + * + * Note: This API should be never accessed out of pkt_capture component. + */ + +#ifndef _WLAN_PKT_CAPTURE_DATA_TXRX_H_ +#define _WLAN_PKT_CAPTURE_DATA_TXRX_H_ + +#include "cdp_txrx_cmn_struct.h" +#include +#include + +/** + * pkt_capture_data_process_type - data pkt types to process + * for packet capture mode + * @TXRX_PROCESS_TYPE_DATA_RX: process RX packets (normal rx + offloaded rx) + * @TXRX_PROCESS_TYPE_DATA_TX: process TX packets (ofloaded tx) + * @TXRX_PROCESS_TYPE_DATA_TX_COMPL: process TX compl packets (normal tx) + */ +enum pkt_capture_data_process_type { + TXRX_PROCESS_TYPE_DATA_RX, + TXRX_PROCESS_TYPE_DATA_TX, + TXRX_PROCESS_TYPE_DATA_TX_COMPL, +}; + +#define TXRX_PKTCAPTURE_PKT_FORMAT_8023 0 +#define TXRX_PKTCAPTURE_PKT_FORMAT_80211 1 + +/** + * pkt_capture_datapkt_process() - process data tx and rx packets + * for pkt capture mode. (normal tx/rx + offloaded tx/rx) + * @vdev_id: vdev id for which packet is captured + * @mon_buf_list: netbuf list + * @type: data process type + * @tid: tid number + * @status: Tx status + * @pkt_format: Frame format + * @bssid: bssid + * @pdev: pdev handle + * + * Return: none + */ +void pkt_capture_datapkt_process( + uint8_t vdev_id, + qdf_nbuf_t mon_buf_list, + enum pkt_capture_data_process_type type, + uint8_t tid, uint8_t status, bool pkt_format, + uint8_t *bssid, htt_pdev_handle pdev); +/** + * pkt_capture_msdu_process_pkts() - process data rx pkts + * @bssid: bssid + * @head_msdu: pointer to head msdu + * @vdev_id: vdev_id + * @pdev: pdev handle + * + * Return: none + */ +void pkt_capture_msdu_process_pkts( + uint8_t *bssid, + qdf_nbuf_t head_msdu, + uint8_t vdev_id, + htt_pdev_handle pdev); + +/** + * pkt_capture_rx_in_order_drop_offload_pkt() - drop offload packets + * @head_msdu: pointer to head msdu + * + * Return: none + */ +void pkt_capture_rx_in_order_drop_offload_pkt(qdf_nbuf_t head_msdu); + +/** + * pkt_capture_rx_in_order_offloaded_pkt() - check offloaded data pkt or not + * @rx_ind_msg: rx_ind_msg + * + * Return: false, if it is not offload pkt + * true, if it is offload pkt + */ +bool pkt_capture_rx_in_order_offloaded_pkt(qdf_nbuf_t rx_ind_msg); +#endif /* End of _WLAN_PKT_CAPTURE_DATA_TXRX_H_ */ diff --git a/components/pkt_capture/core/inc/wlan_pkt_capture_main.h b/components/pkt_capture/core/inc/wlan_pkt_capture_main.h index f5f316275f..00b73f607a 100644 --- a/components/pkt_capture/core/inc/wlan_pkt_capture_main.h +++ b/components/pkt_capture/core/inc/wlan_pkt_capture_main.h @@ -30,6 +30,7 @@ #include #include "wlan_pkt_capture_priv.h" #include "wlan_pkt_capture_objmgr.h" +#include "wlan_objmgr_vdev_obj.h" #define pkt_capture_log(level, args...) \ QDF_TRACE(QDF_MODULE_ID_PKT_CAPTURE, level, ## args) @@ -51,6 +52,13 @@ #define PKT_CAPTURE_ENTER() pkt_capture_debug("enter") #define PKT_CAPTURE_EXIT() pkt_capture_debug("exit") +/** + * pkt_capture_get_vdev() - Get pkt capture objmgr vdev. + * + * Return: pkt capture objmgr vdev + */ +struct wlan_objmgr_vdev *pkt_capture_get_vdev(void); + /** * pkt_capture_vdev_create_notification() - Handler for vdev create notify. * @vdev: vdev which is going to be created by objmgr diff --git a/components/pkt_capture/core/inc/wlan_pkt_capture_mon_thread.h b/components/pkt_capture/core/inc/wlan_pkt_capture_mon_thread.h index 5c28d56dfe..08d96a6a44 100644 --- a/components/pkt_capture/core/inc/wlan_pkt_capture_mon_thread.h +++ b/components/pkt_capture/core/inc/wlan_pkt_capture_mon_thread.h @@ -38,29 +38,35 @@ /* timeout in msec to wait for mon thread to suspend */ #define PKT_CAPTURE_SUSPEND_TIMEOUT 200 -typedef void (*pkt_capture_mon_thread_cb)(void *context, void *monpkt, - uint8_t vdev_id, uint8_t tid, - uint8_t status, bool pkt_format); +typedef void (*pkt_capture_mon_thread_cb)( + void *context, void *ppdev, void *monpkt, + uint8_t vdev_id, uint8_t tid, + uint8_t status, bool pkt_format, + uint8_t *bssid); /* * struct pkt_capture_mon_pkt - mon packet wrapper for mon data from TXRX * @list: List for storing mon packets * @context: Callback context + * @pdev: pointer to pdev handle * @monpkt: Mon skb * @vdev_id: Vdev id to which this packet is destined * @tid: Tid of mon packet * @status: Tx packet status * @pkt_format: Mon packet format, 0 = 802.3 format , 1 = 802.11 format + * @bssid: bssid * @callback: Mon callback */ struct pkt_capture_mon_pkt { struct list_head list; void *context; + void *pdev; void *monpkt; uint8_t vdev_id; uint8_t tid; uint8_t status; bool pkt_format; + uint8_t bssid[QDF_MAC_ADDR_SIZE]; pkt_capture_mon_thread_cb callback; }; diff --git a/components/pkt_capture/core/src/wlan_pkt_capture_data_txrx.c b/components/pkt_capture/core/src/wlan_pkt_capture_data_txrx.c new file mode 100644 index 0000000000..e153e2c335 --- /dev/null +++ b/components/pkt_capture/core/src/wlan_pkt_capture_data_txrx.c @@ -0,0 +1,370 @@ +/* + * Copyright (c) 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. + */ + +/** + * DOC: Implement various notification handlers which are accessed + * internally in pkt_capture component only. + */ + +#include +#include +#include +#include + +/** + * pkt_capture_rx_convert8023to80211() - convert 802.3 packet to 802.11 + * format from rx desc + * @bssid: bssid + * @msdu: netbuf + * @desc: rx desc + * + * Return: none + */ +static void +pkt_capture_rx_convert8023to80211(uint8_t *bssid, qdf_nbuf_t msdu, void *desc) +{ + struct ethernet_hdr_t *eth_hdr; + struct llc_snap_hdr_t *llc_hdr; + struct ieee80211_frame *wh; + uint8_t hdsize, new_hdsize; + struct ieee80211_qoscntl *qos_cntl; + uint16_t seq_no; + uint8_t localbuf[sizeof(struct ieee80211_qosframe_htc_addr4) + + sizeof(struct llc_snap_hdr_t)]; + const uint8_t ethernet_II_llc_snap_header_prefix[] = { + 0xaa, 0xaa, 0x03, 0x00, 0x00, 0x00 }; + uint16_t ether_type; + + struct htt_host_rx_desc_base *rx_desc = desc; + + eth_hdr = (struct ethernet_hdr_t *)qdf_nbuf_data(msdu); + hdsize = sizeof(struct ethernet_hdr_t); + wh = (struct ieee80211_frame *)localbuf; + + wh->i_fc[0] = IEEE80211_FC0_VERSION_0 | IEEE80211_FC0_TYPE_DATA; + *(uint16_t *)wh->i_dur = 0; + + new_hdsize = 0; + + /* DA , BSSID , SA */ + qdf_mem_copy(wh->i_addr1, eth_hdr->dest_addr, + QDF_MAC_ADDR_SIZE); + qdf_mem_copy(wh->i_addr2, bssid, + QDF_MAC_ADDR_SIZE); + qdf_mem_copy(wh->i_addr3, eth_hdr->src_addr, + QDF_MAC_ADDR_SIZE); + + wh->i_fc[1] = IEEE80211_FC1_DIR_FROMDS; + + if (rx_desc->attention.more_data) + wh->i_fc[1] |= IEEE80211_FC1_MORE_DATA; + + if (rx_desc->attention.power_mgmt) + wh->i_fc[1] |= IEEE80211_FC1_PWR_MGT; + + if (rx_desc->attention.fragment) + wh->i_fc[1] |= IEEE80211_FC1_MORE_FRAG; + + if (rx_desc->attention.order) + wh->i_fc[1] |= IEEE80211_FC1_ORDER; + + if (rx_desc->mpdu_start.retry) + wh->i_fc[1] |= IEEE80211_FC1_RETRY; + + seq_no = rx_desc->mpdu_start.seq_num; + seq_no = (seq_no << IEEE80211_SEQ_SEQ_SHIFT) & IEEE80211_SEQ_SEQ_MASK; + qdf_mem_copy(wh->i_seq, &seq_no, sizeof(seq_no)); + + new_hdsize = sizeof(struct ieee80211_frame); + + if (rx_desc->attention.non_qos == 0) { + qos_cntl = + (struct ieee80211_qoscntl *)(localbuf + new_hdsize); + qos_cntl->i_qos[0] = + (rx_desc->mpdu_start.tid & IEEE80211_QOS_TID); + wh->i_fc[0] |= QDF_IEEE80211_FC0_SUBTYPE_QOS; + + qos_cntl->i_qos[1] = 0; + new_hdsize += sizeof(struct ieee80211_qoscntl); + } + + /* + * Prepare llc Header + */ + llc_hdr = (struct llc_snap_hdr_t *)(localbuf + new_hdsize); + ether_type = (eth_hdr->ethertype[0] << 8) | + (eth_hdr->ethertype[1]); + if (ether_type >= ETH_P_802_3_MIN) { + qdf_mem_copy(llc_hdr, + ethernet_II_llc_snap_header_prefix, + sizeof + (ethernet_II_llc_snap_header_prefix)); + if (ether_type == ETHERTYPE_AARP || + ether_type == ETHERTYPE_IPX) { + llc_hdr->org_code[2] = + BTEP_SNAP_ORGCODE_2; + /* 0xf8; bridge tunnel header */ + } + llc_hdr->ethertype[0] = eth_hdr->ethertype[0]; + llc_hdr->ethertype[1] = eth_hdr->ethertype[1]; + new_hdsize += sizeof(struct llc_snap_hdr_t); + } + + /* + * Remove 802.3 Header by adjusting the head + */ + qdf_nbuf_pull_head(msdu, hdsize); + + /* + * Adjust the head and prepare 802.11 Header + */ + qdf_nbuf_push_head(msdu, new_hdsize); + qdf_mem_copy(qdf_nbuf_data(msdu), localbuf, new_hdsize); +} + +void pkt_capture_rx_in_order_drop_offload_pkt(qdf_nbuf_t head_msdu) +{ + while (head_msdu) { + qdf_nbuf_t msdu = head_msdu; + + head_msdu = qdf_nbuf_next(head_msdu); + qdf_nbuf_free(msdu); + } +} + +bool pkt_capture_rx_in_order_offloaded_pkt(qdf_nbuf_t rx_ind_msg) +{ + uint32_t *msg_word; + + msg_word = (uint32_t *)qdf_nbuf_data(rx_ind_msg); + + /* check if it is for offloaded data pkt */ + return HTT_RX_IN_ORD_PADDR_IND_PKT_CAPTURE_MODE_IS_MONITOR_SET + (*(msg_word + 1)); +} + +void pkt_capture_msdu_process_pkts( + uint8_t *bssid, + qdf_nbuf_t head_msdu, + uint8_t vdev_id, htt_pdev_handle pdev) +{ + qdf_nbuf_t loop_msdu, pktcapture_msdu; + qdf_nbuf_t msdu, prev = NULL; + + pktcapture_msdu = NULL; + loop_msdu = head_msdu; + while (loop_msdu) { + msdu = qdf_nbuf_copy(loop_msdu); + + if (msdu) { + qdf_nbuf_push_head(msdu, + HTT_RX_STD_DESC_RESERVATION); + qdf_nbuf_set_next(msdu, NULL); + + if (!(pktcapture_msdu)) { + pktcapture_msdu = msdu; + prev = msdu; + } else { + qdf_nbuf_set_next(prev, msdu); + prev = msdu; + } + } + loop_msdu = qdf_nbuf_next(loop_msdu); + } + + if (!pktcapture_msdu) + return; + + pkt_capture_datapkt_process( + vdev_id, pktcapture_msdu, + TXRX_PROCESS_TYPE_DATA_RX, 0, 0, + TXRX_PKTCAPTURE_PKT_FORMAT_8023, + bssid, pdev); +} + +/** + * pkt_capture_rx_data_cb(): callback to process data rx packets + * for pkt capture mode. (normal rx + offloaded rx) + * @context: objmgr vdev + * @ppdev: device handler + * @nbuf_list: netbuf list + * @vdev_id: vdev id for which packet is captured + * @tid: tid number + * @status: Tx status + * @pkt_format: Frame format + * @bssid: bssid + * + * Return: none + */ +static void +pkt_capture_rx_data_cb( + void *context, void *ppdev, void *nbuf_list, + uint8_t vdev_id, uint8_t tid, + uint8_t status, bool pkt_format, + uint8_t *bssid) +{ + struct pkt_capture_vdev_priv *vdev_priv; + qdf_nbuf_t buf_list = (qdf_nbuf_t)nbuf_list; + struct wlan_objmgr_vdev *vdev = context; + htt_pdev_handle pdev = ppdev; + struct pkt_capture_cb_context *cb_ctx; + qdf_nbuf_t msdu, next_buf; + uint8_t drop_count; + struct htt_host_rx_desc_base *rx_desc; + struct mon_rx_status rx_status = {0}; + uint32_t headroom; + static uint8_t preamble_type; + static uint32_t vht_sig_a_1; + static uint32_t vht_sig_a_2; + + vdev_priv = pkt_capture_vdev_get_priv(vdev); + if (qdf_unlikely(!vdev)) + goto free_buf; + + cb_ctx = vdev_priv->cb_ctx; + if (!cb_ctx || !cb_ctx->mon_cb || !cb_ctx->mon_ctx) + goto free_buf; + + msdu = buf_list; + while (msdu) { + struct ethernet_hdr_t *eth_hdr; + + next_buf = qdf_nbuf_queue_next(msdu); + qdf_nbuf_set_next(msdu, NULL); /* Add NULL terminator */ + + rx_desc = htt_rx_desc(msdu); + + /* + * Only the first mpdu has valid preamble type, so use it + * till the last mpdu is reached + */ + if (rx_desc->attention.first_mpdu) { + preamble_type = rx_desc->ppdu_start.preamble_type; + if (preamble_type == 8 || preamble_type == 9 || + preamble_type == 0x0c || preamble_type == 0x0d) { + vht_sig_a_1 = VHT_SIG_A_1(rx_desc); + vht_sig_a_2 = VHT_SIG_A_2(rx_desc); + } + } else { + rx_desc->ppdu_start.preamble_type = preamble_type; + if (preamble_type == 8 || preamble_type == 9 || + preamble_type == 0x0c || preamble_type == 0x0d) { + VHT_SIG_A_1(rx_desc) = vht_sig_a_1; + VHT_SIG_A_2(rx_desc) = vht_sig_a_2; + } + } + + if (rx_desc->attention.last_mpdu) { + preamble_type = 0; + vht_sig_a_1 = 0; + vht_sig_a_2 = 0; + } + + qdf_nbuf_pull_head(msdu, HTT_RX_STD_DESC_RESERVATION); + + /* + * Get the channel info and update the rx status + */ + + /* need to update this to fill rx_status*/ + htt_rx_mon_get_rx_status(pdev, rx_desc, &rx_status); + rx_status.chan_noise_floor = NORMALIZED_TO_NOISE_FLOOR; + + /* clear IEEE80211_RADIOTAP_F_FCS flag*/ + rx_status.rtap_flags &= ~(BIT(4)); + rx_status.rtap_flags &= ~(BIT(2)); + + /* + * convert 802.3 header format into 802.11 format + */ + if (vdev_id == HTT_INVALID_VDEV) { + eth_hdr = (struct ethernet_hdr_t *)qdf_nbuf_data(msdu); + qdf_mem_copy(bssid, eth_hdr->src_addr, + QDF_MAC_ADDR_SIZE); + } + + pkt_capture_rx_convert8023to80211(bssid, msdu, rx_desc); + + /* + * Calculate the headroom and adjust head + * to prepare radiotap header. + */ + headroom = qdf_nbuf_headroom(msdu); + qdf_nbuf_update_radiotap(&rx_status, msdu, headroom); + + if (QDF_STATUS_SUCCESS != + cb_ctx->mon_cb(cb_ctx->mon_ctx, msdu)) { + pkt_capture_err("Frame Rx to HDD failed"); + qdf_nbuf_free(msdu); + } + msdu = next_buf; + } + + return; + +free_buf: + drop_count = pkt_capture_drop_nbuf_list(buf_list); +} + +void pkt_capture_datapkt_process( + uint8_t vdev_id, + qdf_nbuf_t mon_buf_list, + enum pkt_capture_data_process_type type, + uint8_t tid, uint8_t status, bool pkt_format, + uint8_t *bssid, htt_pdev_handle pdev) +{ + uint8_t drop_count; + struct pkt_capture_mon_pkt *pkt; + pkt_capture_mon_thread_cb callback = NULL; + struct wlan_objmgr_vdev *vdev; + + vdev = pkt_capture_get_vdev(); + if (!vdev) + goto drop_rx_buf; + + pkt = pkt_capture_alloc_mon_pkt(vdev); + if (!pkt) + goto drop_rx_buf; + + switch (type) { + case TXRX_PROCESS_TYPE_DATA_RX: + callback = pkt_capture_rx_data_cb; + break; + case TXRX_PROCESS_TYPE_DATA_TX: + break; + case TXRX_PROCESS_TYPE_DATA_TX_COMPL: + break; + default: + return; + } + + pkt->callback = callback; + pkt->context = (void *)vdev; + pkt->pdev = (void *)pdev; + pkt->monpkt = (void *)mon_buf_list; + pkt->vdev_id = vdev_id; + pkt->tid = tid; + pkt->status = status; + pkt->pkt_format = pkt_format; + qdf_mem_copy(pkt->bssid, bssid, QDF_MAC_ADDR_SIZE); + pkt_capture_indicate_monpkt(vdev, pkt); + return; + +drop_rx_buf: + drop_count = pkt_capture_drop_nbuf_list(mon_buf_list); +} diff --git a/components/pkt_capture/core/src/wlan_pkt_capture_main.c b/components/pkt_capture/core/src/wlan_pkt_capture_main.c index 025e16e9e5..c54b6997b6 100644 --- a/components/pkt_capture/core/src/wlan_pkt_capture_main.c +++ b/components/pkt_capture/core/src/wlan_pkt_capture_main.c @@ -27,6 +27,13 @@ #include "wlan_pkt_capture_mgmt_txrx.h" #include "target_if_pkt_capture.h" +static struct wlan_objmgr_vdev *gp_pkt_capture_vdev; + +struct wlan_objmgr_vdev *pkt_capture_get_vdev() +{ + return gp_pkt_capture_vdev; +} + enum pkt_capture_mode pkt_capture_get_mode(struct wlan_objmgr_psoc *psoc) { struct pkt_psoc_priv *psoc_priv; @@ -296,6 +303,7 @@ pkt_capture_vdev_create_notification(struct wlan_objmgr_vdev *vdev, void *arg) } vdev_priv->vdev = vdev; + gp_pkt_capture_vdev = vdev; status = pkt_capture_callback_ctx_create(vdev_priv); if (!QDF_IS_STATUS_SUCCESS(status)) { @@ -366,6 +374,7 @@ pkt_capture_vdev_destroy_notification(struct wlan_objmgr_vdev *vdev, void *arg) pkt_capture_mon_context_destroy(vdev_priv); pkt_capture_callback_ctx_destroy(vdev_priv); qdf_mem_free(vdev_priv); + gp_pkt_capture_vdev = NULL; return status; } diff --git a/components/pkt_capture/core/src/wlan_pkt_capture_mgmt_txrx.c b/components/pkt_capture/core/src/wlan_pkt_capture_mgmt_txrx.c index e75bfb143e..fdf9e9d5ae 100644 --- a/components/pkt_capture/core/src/wlan_pkt_capture_mgmt_txrx.c +++ b/components/pkt_capture/core/src/wlan_pkt_capture_mgmt_txrx.c @@ -44,9 +44,9 @@ * Return: none */ static void -pkt_capture_mgmtpkt_cb(void *context, void *nbuf_list, +pkt_capture_mgmtpkt_cb(void *context, void *ppdev, void *nbuf_list, uint8_t vdev_id, uint8_t tid, uint8_t status, - bool pkt_format) + bool pkt_format, uint8_t *bssid) { struct pkt_capture_vdev_priv *vdev_priv; struct wlan_objmgr_psoc *psoc = context; @@ -293,7 +293,7 @@ pkt_capture_mgmt_rx_data_cb(struct wlan_objmgr_psoc *psoc, qdf_nbuf_t nbuf; int buf_len; - if (!(pkt_capture_get_mode(psoc) & PKT_CAPTURE_MODE_MGMT_ONLY)) + if (!(pkt_capture_get_pktcap_mode(psoc) & PKT_CAPTURE_MODE_MGMT_ONLY)) return QDF_STATUS_E_FAILURE; buf_len = qdf_nbuf_len(wbuf); diff --git a/components/pkt_capture/core/src/wlan_pkt_capture_mon_thread.c b/components/pkt_capture/core/src/wlan_pkt_capture_mon_thread.c index 7a3e80f40d..50056c7e89 100644 --- a/components/pkt_capture/core/src/wlan_pkt_capture_mon_thread.c +++ b/components/pkt_capture/core/src/wlan_pkt_capture_mon_thread.c @@ -209,8 +209,8 @@ pkt_capture_process_from_queue(struct pkt_capture_mon_context *mon_ctx) spin_unlock_bh(&mon_ctx->mon_queue_lock); vdev_id = pkt->vdev_id; tid = pkt->tid; - pkt->callback(pkt->context, pkt->monpkt, vdev_id, - tid, pkt->status, pkt->pkt_format); + pkt->callback(pkt->context, pkt->pdev, pkt->monpkt, vdev_id, + tid, pkt->status, pkt->pkt_format, pkt->bssid); pkt_capture_free_mon_pkt(mon_ctx, pkt); spin_lock_bh(&mon_ctx->mon_queue_lock); } diff --git a/components/pkt_capture/dispatcher/inc/wlan_pkt_capture_ucfg_api.h b/components/pkt_capture/dispatcher/inc/wlan_pkt_capture_ucfg_api.h index 15916d0ce4..9a5f141279 100644 --- a/components/pkt_capture/dispatcher/inc/wlan_pkt_capture_ucfg_api.h +++ b/components/pkt_capture/dispatcher/inc/wlan_pkt_capture_ucfg_api.h @@ -28,6 +28,8 @@ #include #include "wlan_pkt_capture_objmgr.h" #include "wlan_pkt_capture_public_structs.h" +#include "wlan_pkt_capture_mon_thread.h" +#include #ifdef WLAN_FEATURE_PKT_CAPTURE /** @@ -155,6 +157,38 @@ ucfg_pkt_capture_mgmt_tx_completion( * Return: 0 on success, -EINVAL on failure */ int ucfg_pkt_capture_enable_ops(struct wlan_objmgr_vdev *vdev); + +/** + * ucfg_pkt_capture_rx_msdu_process() - process data rx pkts + * @bssid: bssid + * @head_msdu: pointer to head msdu + * @vdev_id: vdev_id + * @pdev: pdev handle + * + * Return: none + */ +void ucfg_pkt_capture_rx_msdu_process( + uint8_t *bssid, + qdf_nbuf_t head_msdu, + uint8_t vdev_id, htt_pdev_handle pdev); + +/** + * ucfg_pkt_capture_rx_offloaded_pkt() - check offloaded data pkt or not + * @rx_ind_msg: rx_ind_msg + * + * Return: 0 not an offload pkt + * 1 offload pkt + */ +bool ucfg_pkt_capture_rx_offloaded_pkt(qdf_nbuf_t rx_ind_msg); + +/** + * ucfg_pkt_capture_rx_drop_offload_pkt() - drop offload packets + * @head_msdu: pointer to head msdu + * + * Return: none + */ +void ucfg_pkt_capture_rx_drop_offload_pkt(qdf_nbuf_t head_msdu); + #else static inline QDF_STATUS ucfg_pkt_capture_init(void) @@ -226,5 +260,24 @@ ucfg_pkt_capture_mgmt_tx_completion(struct wlan_objmgr_pdev *pdev, struct mgmt_offload_event_params *params) { } + +static inline void +ucfg_pkt_capture_rx_msdu_process( + uint8_t *bssid, + qdf_nbuf_t head_msdu, + uint8_t vdev_id, htt_pdev_handle pdev) +{ +} + +static inline bool +ucfg_pkt_capture_rx_offloaded_pkt(qdf_nbuf_t rx_ind_msg) +{ + return false; +} + +static inline void +ucfg_pkt_capture_rx_drop_offload_pkt(qdf_nbuf_t head_msdu) +{ +} #endif /* WLAN_FEATURE_PKT_CAPTURE */ #endif /* _WLAN_PKT_CAPTURE_UCFG_API_H_ */ diff --git a/components/pkt_capture/dispatcher/src/wlan_pkt_capture_ucfg_api.c b/components/pkt_capture/dispatcher/src/wlan_pkt_capture_ucfg_api.c index 6f68878cad..e891125620 100644 --- a/components/pkt_capture/dispatcher/src/wlan_pkt_capture_ucfg_api.c +++ b/components/pkt_capture/dispatcher/src/wlan_pkt_capture_ucfg_api.c @@ -26,6 +26,7 @@ #include "wlan_pkt_capture_mon_thread.h" #include "wlan_pkt_capture_mgmt_txrx.h" #include "target_if_pkt_capture.h" +#include "wlan_pkt_capture_data_txrx.h" enum pkt_capture_mode ucfg_pkt_capture_get_mode(struct wlan_objmgr_psoc *psoc) { @@ -271,3 +272,22 @@ int ucfg_pkt_capture_enable_ops(struct wlan_objmgr_vdev *vdev) return 0; } + +void ucfg_pkt_capture_rx_msdu_process( + uint8_t *bssid, + qdf_nbuf_t head_msdu, + uint8_t vdev_id, htt_pdev_handle pdev) +{ + pkt_capture_msdu_process_pkts(bssid, head_msdu, + vdev_id, pdev); +} + +bool ucfg_pkt_capture_rx_offloaded_pkt(qdf_nbuf_t rx_ind_msg) +{ + return pkt_capture_rx_in_order_offloaded_pkt(rx_ind_msg); +} + +void ucfg_pkt_capture_rx_drop_offload_pkt(qdf_nbuf_t head_msdu) +{ + pkt_capture_rx_in_order_drop_offload_pkt(head_msdu); +} diff --git a/core/dp/htt/htt_internal.h b/core/dp/htt/htt_internal.h index 17bd2cbc9c..6e05b2f2f3 100644 --- a/core/dp/htt/htt_internal.h +++ b/core/dp/htt/htt_internal.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, 2014-2019 The Linux Foundation. All rights reserved. + * Copyright (c) 2011, 2014-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 @@ -1119,6 +1119,19 @@ int htt_rx_mon_amsdu_rx_in_order_pop_ll(htt_pdev_handle pdev, qdf_nbuf_t *head_msdu, qdf_nbuf_t *tail_msdu, uint32_t *replenish_cnt); + +/** + * htt_rx_mon_get_rx_status() - Update information about the rx status, + * which is used later for radiotap updation. + * @pdev: Pointer to pdev handle + * @rx_desc: Pointer to struct htt_host_rx_desc_base + * @rx_status: Return variable updated with rx_status + * + * Return: None + */ +void htt_rx_mon_get_rx_status(htt_pdev_handle pdev, + struct htt_host_rx_desc_base *rx_desc, + struct mon_rx_status *rx_status); #else static inline int htt_rx_mon_amsdu_rx_in_order_pop_ll(htt_pdev_handle pdev, @@ -1129,6 +1142,13 @@ int htt_rx_mon_amsdu_rx_in_order_pop_ll(htt_pdev_handle pdev, { return 0; } + +static inline +void htt_rx_mon_get_rx_status(htt_pdev_handle pdev, + struct htt_host_rx_desc_base *rx_desc, + struct mon_rx_status *rx_status) +{ +} #endif #endif /* _HTT_INTERNAL__H_ */ diff --git a/core/dp/htt/htt_monitor_rx.c b/core/dp/htt/htt_monitor_rx.c index d76521279d..e8899e3814 100644 --- a/core/dp/htt/htt_monitor_rx.c +++ b/core/dp/htt/htt_monitor_rx.c @@ -458,17 +458,9 @@ static uint8_t htt_mon_rx_get_rtap_flags(struct htt_host_rx_desc_base *rx_desc) return rtap_flags; } -/** - * htt_rx_mon_get_rx_status() - Update information about the rx status, - * which is used later for radiotap updation. - * @rx_desc: Pointer to struct htt_host_rx_desc_base - * @rx_status: Return variable updated with rx_status - * - * Return: None - */ -static void htt_rx_mon_get_rx_status(htt_pdev_handle pdev, - struct htt_host_rx_desc_base *rx_desc, - struct mon_rx_status *rx_status) +void htt_rx_mon_get_rx_status(htt_pdev_handle pdev, + struct htt_host_rx_desc_base *rx_desc, + struct mon_rx_status *rx_status) { uint16_t channel_flags = 0; struct mon_channel *ch_info = &pdev->mon_ch_info; diff --git a/core/dp/txrx/ol_rx.c b/core/dp/txrx/ol_rx.c index 382ece009d..140e4a6615 100644 --- a/core/dp/txrx/ol_rx.c +++ b/core/dp/txrx/ol_rx.c @@ -56,6 +56,7 @@ #include #include #include +#include #ifndef OL_RX_INDICATION_MAX_RECORDS #define OL_RX_INDICATION_MAX_RECORDS 2048 @@ -1561,6 +1562,7 @@ ol_rx_in_order_indication_handler(ol_txrx_pdev_handle pdev, { struct ol_txrx_vdev_t *vdev = NULL; struct ol_txrx_peer_t *peer = NULL; + struct ol_txrx_peer_t *peer_head = NULL; htt_pdev_handle htt_pdev = NULL; int status; qdf_nbuf_t head_msdu = NULL, tail_msdu = NULL; @@ -1569,6 +1571,14 @@ ol_rx_in_order_indication_handler(ol_txrx_pdev_handle pdev, uint32_t msdu_count; uint8_t pktlog_bit; uint32_t filled = 0; + uint8_t bssid[QDF_MAC_ADDR_SIZE]; + bool offloaded_pkt; + struct ol_txrx_soc_t *soc = cds_get_context(QDF_MODULE_ID_SOC); + + if (qdf_unlikely(!soc)) { + ol_txrx_err("soc is NULL"); + return; + } if (tid >= OL_TXRX_NUM_EXT_TIDS) { ol_txrx_err("invalid tid, %u", tid); @@ -1632,6 +1642,43 @@ ol_rx_in_order_indication_handler(ol_txrx_pdev_handle pdev, /* rx_opt_proc takes a NULL-terminated list of msdu netbufs */ qdf_nbuf_set_next(tail_msdu, NULL); + /* Packet Capture Mode */ + + if ((ucfg_pkt_capture_get_mode((void *)soc->psoc) & + PKT_CAPTURE_MODE_DATA_ONLY)) { + offloaded_pkt = ucfg_pkt_capture_rx_offloaded_pkt(rx_ind_msg); + if (peer) { + vdev = peer->vdev; + if (peer->vdev) { + qdf_spin_lock_bh(&pdev->peer_ref_mutex); + peer_head = TAILQ_FIRST(&vdev->peer_list); + qdf_spin_unlock_bh(&pdev->peer_ref_mutex); + if (peer_head) { + qdf_spin_lock_bh( + &peer_head->peer_info_lock); + qdf_mem_copy(bssid, + &peer_head->mac_addr.raw, + QDF_MAC_ADDR_SIZE); + qdf_spin_unlock_bh( + &peer_head->peer_info_lock); + + ucfg_pkt_capture_rx_msdu_process( + bssid, head_msdu, + peer->vdev->vdev_id, + htt_pdev); + } + } + } else if (offloaded_pkt) { + ucfg_pkt_capture_rx_msdu_process( + bssid, head_msdu, + HTT_INVALID_VDEV, + htt_pdev); + + ucfg_pkt_capture_rx_drop_offload_pkt(head_msdu); + return; + } + } + /* Pktlog */ ol_rx_send_pktlog_event(pdev, peer, head_msdu, pktlog_bit); diff --git a/core/dp/txrx/ol_rx_defrag.c b/core/dp/txrx/ol_rx_defrag.c index b469820339..af9b04b112 100644 --- a/core/dp/txrx/ol_rx_defrag.c +++ b/core/dp/txrx/ol_rx_defrag.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011-2019 The Linux Foundation. All rights reserved. + * Copyright (c) 2011-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 @@ -58,6 +58,7 @@ #include #include #include /* qdf_system_time */ +#include #define DEFRAG_IEEE80211_ADDR_EQ(a1, a2) \ (!qdf_mem_cmp(a1, a2, QDF_MAC_ADDR_SIZE)) @@ -653,7 +654,14 @@ ol_rx_defrag(ol_txrx_pdev_handle pdev, struct ieee80211_frame *wh; uint8_t key[DEFRAG_IEEE80211_KEY_LEN]; htt_pdev_handle htt_pdev = pdev->htt_pdev; + struct ol_txrx_peer_t *peer_head = NULL; + uint8_t bssid[QDF_MAC_ADDR_SIZE]; + struct ol_txrx_soc_t *soc = cds_get_context(QDF_MODULE_ID_SOC); + if (qdf_unlikely(!soc)) { + ol_txrx_err("soc is NULL"); + return; + } vdev = peer->vdev; /* bypass defrag for safe mode */ @@ -770,6 +778,33 @@ ol_rx_defrag(ol_txrx_pdev_handle pdev, if (ol_cfg_frame_type(pdev->ctrl_pdev) == wlan_frm_fmt_802_3) ol_rx_defrag_nwifi_to_8023(pdev, msdu); + /* Packet Capture Mode */ + + if ((ucfg_pkt_capture_get_mode((void *)soc->psoc) & + PKT_CAPTURE_MODE_DATA_ONLY)) { + if (peer) { + if (peer->vdev) { + qdf_spin_lock_bh(&pdev->peer_ref_mutex); + peer_head = TAILQ_FIRST(&vdev->peer_list); + qdf_spin_unlock_bh(&pdev->peer_ref_mutex); + if (peer_head) { + qdf_spin_lock_bh( + &peer_head->peer_info_lock); + qdf_mem_copy(bssid, + &peer_head->mac_addr.raw, + QDF_MAC_ADDR_SIZE); + qdf_spin_unlock_bh( + &peer_head->peer_info_lock); + + ucfg_pkt_capture_rx_msdu_process( + bssid, msdu, + vdev->vdev_id, + htt_pdev); + } + } + } + } + ol_rx_fwd_check(vdev, peer, tid, msdu); }